|
|
package com.sitech.ismp.check.downtime;
|
|
|
|
|
|
import com.sitech.ismp.app.event.KPI2Event;
|
|
|
import com.sitech.ismp.coll.basic.TblATO_EVENT;
|
|
|
import com.sitech.util.Base62Util;
|
|
|
import com.sitech.util.RandomGUID;
|
|
|
import com.sitech.util.upload.RomoteController;
|
|
|
import com.sitech.util.upload.SSHThread;
|
|
|
import com.sitech.util.upload.TelnetThread;
|
|
|
import org.apache.commons.lang.StringUtils;
|
|
|
import org.apache.log4j.Logger;
|
|
|
|
|
|
import java.io.BufferedReader;
|
|
|
import java.io.IOException;
|
|
|
import java.io.InputStreamReader;
|
|
|
import java.text.ParseException;
|
|
|
import java.text.SimpleDateFormat;
|
|
|
import java.util.Date;
|
|
|
import java.util.Random;
|
|
|
|
|
|
/**
|
|
|
* @author frank zmm@honggroup.com.cn
|
|
|
* @Description: 宕机检测MBean对应Server类。
|
|
|
* ping的布尔结果 true:能ping通, false:ping不通
|
|
|
* ssh连接的布尔结果 true:能ssh连接, false:ssh连接异常
|
|
|
* @Package com.sitech.ismp.check.downtime
|
|
|
* @ClassName: com.sitech.ismp.check.downtime.DowntimeServer
|
|
|
* @date 2017年04月12日 16:22
|
|
|
*/
|
|
|
public class DowntimeServer implements Runnable{
|
|
|
|
|
|
private static Logger log=Logger.getLogger(DowntimeServer.class);
|
|
|
private DowntimeBean bean;
|
|
|
DowntimeHistoryDao historyDao=new DowntimeHistoryDao();
|
|
|
|
|
|
public DowntimeServer(DowntimeBean bean){
|
|
|
this.bean=bean;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 1 对表中的主机进行ping操作。
|
|
|
* 2 对表中的主机进行SSH登录认证。
|
|
|
* 3 发送告警信息。
|
|
|
*/
|
|
|
@Override
|
|
|
public void run(){
|
|
|
getPingResult(bean);
|
|
|
getSshResult(bean);
|
|
|
sendEvent2Workstation(bean);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 将每个IP ping后的结果设置到pingState属性上。
|
|
|
* @param bean
|
|
|
* @return
|
|
|
*/
|
|
|
public void getPingResult(DowntimeBean bean){
|
|
|
String ipAddr=null;
|
|
|
log.info("============================== ping all parames ======================");
|
|
|
log.info(bean.toString());
|
|
|
ipAddr=bean.getDEVICE_IP();
|
|
|
boolean temp=pingIpAddress(ipAddr);
|
|
|
bean.setPingState(temp);
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 进行SSH连接,并设置对应告警的内容。
|
|
|
* @param bean
|
|
|
* @return
|
|
|
*/
|
|
|
public void getSshResult(DowntimeBean bean){
|
|
|
boolean pingState=bean.isPingState(); // true:能ping通, false:ping不通
|
|
|
log.info("========== pingState=== "+pingState+"==========");
|
|
|
boolean sshState=contentWithSsh(bean);
|
|
|
log.info("========== sshState=== "+sshState+"==========");
|
|
|
if(!pingState){ // ping 不通 false
|
|
|
if(!sshState){ // ssh 不能连接 严重告警
|
|
|
bean.setWarningLevel(1);
|
|
|
bean.setWarningResult(bean.getDEVICE_IP()+" 的主机连接异常,请检查网络是否正常或主机宕机!");
|
|
|
log.info("========== bean.setWarningResult sshState ="+sshState+",=ip is ["+bean.getDEVICE_IP()+"] host connect error");
|
|
|
}
|
|
|
}else{ //能ping 通
|
|
|
if(!sshState){ // ssh 不能连接 重要告警
|
|
|
bean.setWarningLevel(2);
|
|
|
bean.setWarningResult(bean.getDEVICE_IP()+" 的主机不能进行登录,请检查用户名或密码!!");
|
|
|
log.info("========== bean.setWarningResult sshState ="+sshState+",=ip is["+bean.getDEVICE_IP()+"] host login error");
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 将告警信息发送到Workstation。
|
|
|
* 当ping的结果为false的时候才发送。
|
|
|
* @param bean
|
|
|
*/
|
|
|
private void sendEvent2Workstation(DowntimeBean bean){
|
|
|
log.info("******************************************************");
|
|
|
log.info("*************** sendEvent2Workstation ****************");
|
|
|
log.info("******************************************************");
|
|
|
log.info(bean.toString());
|
|
|
if(!bean.isSshState()){
|
|
|
KPI2Event event=new KPI2Event();
|
|
|
TblATO_EVENT tblato_event = new TblATO_EVENT();
|
|
|
String eventId= RandomGUID.getRandomGUID();
|
|
|
try {
|
|
|
tblato_event.setEVENT_ID(eventId); // 随即生成一个GUID作为唯一键
|
|
|
tblato_event.setUNIT_ID(bean.getUnitId()); // UNIT_ID在页面显示的为平台类型。
|
|
|
tblato_event.setKPI_ID("FM-00-01-001-999");
|
|
|
tblato_event.setKPI_VALUE(bean.getWarningResult());
|
|
|
tblato_event.setEVENT_TITLE(bean.getWarningResult());
|
|
|
tblato_event.setEVENT_CLASS(bean.getWarningLevel()); // 告警级别
|
|
|
tblato_event.setCLL_TIME(new java.util.Date());
|
|
|
tblato_event.setGENERANT_TIME(new java.util.Date());
|
|
|
tblato_event.setCFG_GUID(RandomGUID.getRandomGUID());
|
|
|
log.info("hava finish set values to TblATO_EVENT!");
|
|
|
} catch (ParseException e) {
|
|
|
log.error("set values to TblATO_EVENT hava error!",e);
|
|
|
}
|
|
|
try {
|
|
|
event.sendEvent2Workstation(tblato_event);
|
|
|
addDowntimeHistory(bean);
|
|
|
log.info("have write object(TblATO_EVENT) to Workstation!");
|
|
|
} catch (Exception e) {
|
|
|
log.error("have write object(TblATO_EVENT) to Workstation have error!",e);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
private void addDowntimeHistory(DowntimeBean bean){
|
|
|
DowntimeHistoryBean historyBean=new DowntimeHistoryBean();
|
|
|
historyBean.setDEVICE_ID(bean.getDEVICE_ID());
|
|
|
historyBean.setDEVICE_IP(bean.getDEVICE_IP());
|
|
|
SimpleDateFormat formaF=new SimpleDateFormat("yyyy-MM-dd");
|
|
|
String date=formaF.format(new Date())+"";
|
|
|
date=date.substring(0,10);
|
|
|
historyBean.setCREATE_DATE(date);
|
|
|
historyDao.addDowntimeHistory(historyBean);
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 获取ping 后的结果,是否可以平通指定的IP。
|
|
|
* @param ipAddr
|
|
|
* @return
|
|
|
*/
|
|
|
private boolean pingIpAddress(String ipAddr){
|
|
|
int pingErrorCount=0; // ping 不通的次数,ping3次。
|
|
|
int interval=8; // 时间间隔8秒。
|
|
|
boolean flag=false;
|
|
|
boolean temp=false;
|
|
|
for(int i=0;i<3;i++){
|
|
|
temp=executeCommand(ipAddr); // ping不通返回false。
|
|
|
log.info("["+ipAddr+"]ping result is ["+temp+"],(true:can connect;false:can't connect)");
|
|
|
if(!temp){
|
|
|
pingErrorCount++;
|
|
|
}
|
|
|
try {
|
|
|
Thread.sleep(interval*1000);
|
|
|
log.info("ping ["+ipAddr+"] trread sleep "+interval+" secound........");
|
|
|
} catch (InterruptedException e) {
|
|
|
e.printStackTrace();
|
|
|
}
|
|
|
}
|
|
|
if(pingErrorCount == 3){
|
|
|
log.info("["+ipAddr+"] can't connect 3 times.");
|
|
|
}else{
|
|
|
flag=true;
|
|
|
log.info("["+ipAddr+"] can connect.");
|
|
|
}
|
|
|
return flag;
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 进行ssh连接,判断是否可以连接成功。
|
|
|
* windows操作系统使用 TelnetThread类连接。 Windows的客户端需要配置并开启Telnet相关的服务。
|
|
|
* @return
|
|
|
*/
|
|
|
private boolean contentWithSsh(DowntimeBean bean){
|
|
|
String protocol=bean.getPROTOCOL();
|
|
|
String ipAddr=bean.getDEVICE_IP();
|
|
|
String deviceAlias=bean.getDEVICE_ALIAS();
|
|
|
int protocolPort=bean.getPROTOCOL_PORT();
|
|
|
String userName=bean.getUSER_NAME();
|
|
|
String password=bean.getPASSWORD();
|
|
|
bean.setUnitId(getUnitId(deviceAlias));
|
|
|
log.info("execute contentWithSsh method ......");
|
|
|
boolean temp=false;
|
|
|
RomoteController tt = null;
|
|
|
log.info("host params is: ipAddr="+ipAddr+",protocol="+protocol+",protocolPort="+protocolPort+",userName="+userName);
|
|
|
if(loginParamterIsOk(protocol,ipAddr,protocolPort,userName,password,deviceAlias)){
|
|
|
try {
|
|
|
if (protocol != null && protocol.equalsIgnoreCase("telnet")) {
|
|
|
tt = new TelnetThread(ipAddr, protocolPort, userName, password);
|
|
|
} else if (protocol != null && protocol.equalsIgnoreCase("ssh")) {
|
|
|
tt = new SSHThread(ipAddr, protocolPort, userName, password);
|
|
|
}else{
|
|
|
log.error("===================== unknown protocol =====================");
|
|
|
}
|
|
|
}catch (Exception e){
|
|
|
log.error(protocol+"connect have exception!");
|
|
|
}
|
|
|
tt.initial();
|
|
|
boolean flag=tt.isAuthorized();
|
|
|
log.info("******************* tt.isAuthorized() result is "+flag);
|
|
|
if (flag){ // 认证通过
|
|
|
log.info(ipAddr+" SSH connect,Authorized result is true authorized success!");
|
|
|
temp=true;
|
|
|
bean.setSshState(true);
|
|
|
}else{
|
|
|
log.info(ipAddr+" SSH connect,Authorized result is false authorized fail!!");
|
|
|
bean.setSshState(false);
|
|
|
}
|
|
|
}
|
|
|
return temp;
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 判断所有的参数是否为空。
|
|
|
* @param protocol 协议类型
|
|
|
* @param ipAddr IP地址
|
|
|
* @param protocolPort 协议端口
|
|
|
* @param userName 用户名
|
|
|
* @param password 密码
|
|
|
* @param deviceAlias 主机别名
|
|
|
* @return
|
|
|
*/
|
|
|
private boolean loginParamterIsOk(String protocol,String ipAddr,int protocolPort,String userName,
|
|
|
String password,String deviceAlias){
|
|
|
boolean flag=true;
|
|
|
if(StringUtils.isEmpty(protocol)){
|
|
|
flag=false;
|
|
|
}
|
|
|
if(StringUtils.isEmpty(ipAddr)){
|
|
|
flag=false;
|
|
|
}
|
|
|
if(StringUtils.isEmpty(protocolPort+"")){
|
|
|
flag=false;
|
|
|
}
|
|
|
if(StringUtils.isEmpty(userName)){
|
|
|
flag=false;
|
|
|
}
|
|
|
if(StringUtils.isEmpty(password)){
|
|
|
flag=false;
|
|
|
}
|
|
|
if(StringUtils.isEmpty(deviceAlias)){
|
|
|
flag=false;
|
|
|
}
|
|
|
return flag;
|
|
|
}
|
|
|
|
|
|
|
|
|
private String getUnitId(String deviceAlias){
|
|
|
StringBuffer bf=new StringBuffer("10-10-99-98:");
|
|
|
bf.append(deviceAlias).append("_").append(getEncryptStr());
|
|
|
return bf.toString();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 返回加密后的一个唯一字符串。
|
|
|
* @return
|
|
|
*/
|
|
|
private String getEncryptStr(){
|
|
|
SimpleDateFormat forma=new SimpleDateFormat("yyMMddHHmmss");
|
|
|
Random rr= new Random();
|
|
|
String str=rr.nextInt(999)+forma.format(new Date())+rr.nextInt(999);
|
|
|
return Base62Util.encode(Long.parseLong(str));
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 返回ping后的结果。
|
|
|
* @param ipAddr ip 地址。
|
|
|
* @return
|
|
|
*/
|
|
|
private boolean executeCommand(String ipAddr){
|
|
|
String command = "/bin/ping -c 3 -w 3 " + ipAddr;;
|
|
|
// 执行command 命令。
|
|
|
boolean flag=false;
|
|
|
String line = null;
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
Runtime runtime = Runtime.getRuntime();
|
|
|
Process process = null;
|
|
|
long startTime = new Date().getTime();
|
|
|
try {
|
|
|
process = runtime.exec(command);
|
|
|
} catch (IOException e) {
|
|
|
log.error("execute command ["+command+"] has some error!");
|
|
|
}
|
|
|
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
|
|
try {
|
|
|
while ((line = bufferedReader.readLine()) != null) {
|
|
|
sb.append(line + "\n");
|
|
|
}
|
|
|
} catch (IOException e) {
|
|
|
log.error("======== bufferedReader.readLine() has some error!");
|
|
|
}
|
|
|
|
|
|
String pingResult=sb.toString();
|
|
|
/**
|
|
|
* 当执行结果出现下面字符说明已经执行完成。
|
|
|
* ping 通的时候 结果包含【min/avg/max/mdev】
|
|
|
* ping 不通的时候 结果包含【100% packet loss】
|
|
|
*/
|
|
|
if(pingResult.contains("100% packet loss") || (pingResult.contains("min/avg/max/mdev"))){
|
|
|
process.destroy();
|
|
|
log.info("execute command ["+command+"] finish!");
|
|
|
}
|
|
|
|
|
|
|
|
|
String os = System.getProperty("os.name").toLowerCase();
|
|
|
log.info("------------ operator system is :" + os);
|
|
|
|
|
|
// 解析command命令结果,包含【100% packet loss】 意味着ping不通,返回 false。
|
|
|
if(os.indexOf("linux") >= 0){
|
|
|
if (!StringUtils.isEmpty(pingResult)) {
|
|
|
if(!pingResult.contains("100% packet loss")){
|
|
|
flag = true;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return flag;
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 添加已经发送的告警信息。
|
|
|
* @param bean,取出对象中的ID与IP,外加时间(年月日)
|
|
|
*/
|
|
|
public void addSendedEvent(DowntimeBean bean){
|
|
|
|
|
|
}
|
|
|
|
|
|
} |