|
|
package com.sitech.ismp.check.downtime;
|
|
|
|
|
|
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 org.snmp4j.CommunityTarget;
|
|
|
import org.snmp4j.PDU;
|
|
|
import org.snmp4j.Snmp;
|
|
|
import org.snmp4j.TransportMapping;
|
|
|
import org.snmp4j.event.ResponseEvent;
|
|
|
import org.snmp4j.mp.SnmpConstants;
|
|
|
import org.snmp4j.smi.Address;
|
|
|
import org.snmp4j.smi.GenericAddress;
|
|
|
import org.snmp4j.smi.OID;
|
|
|
import org.snmp4j.smi.OctetString;
|
|
|
import org.snmp4j.smi.UdpAddress;
|
|
|
import org.snmp4j.smi.VariableBinding;
|
|
|
import org.snmp4j.transport.DefaultUdpTransportMapping;
|
|
|
|
|
|
import java.io.BufferedReader;
|
|
|
import java.io.IOException;
|
|
|
import java.io.InputStreamReader;
|
|
|
import java.net.InetAddress;
|
|
|
import java.net.UnknownHostException;
|
|
|
import java.sql.Connection;
|
|
|
import java.sql.DriverManager;
|
|
|
import java.sql.SQLException;
|
|
|
import java.util.Date;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.UUID;
|
|
|
|
|
|
/**
|
|
|
* @author frank zmm@honggroup.com.cn
|
|
|
* @Description: 检查主机,数据库,中间件的连接状态实现类。
|
|
|
* @Package com.sitech.ismp.check.downtime
|
|
|
* @ClassName: com.sitech.ismp.check.downtime.CheckConnectionService
|
|
|
* @date 2017年04月22日 14:36
|
|
|
*/
|
|
|
public class CheckConnectionService {
|
|
|
|
|
|
private static Logger log= Logger.getLogger(CheckConnectionService.class);
|
|
|
private Snmp mSnmp = null;
|
|
|
private CommunityTarget mCommunityTarget = null;
|
|
|
|
|
|
|
|
|
|
|
|
public String getDbConnectionState(ParamterBean bean){
|
|
|
boolean state=contentWithJdbc(bean);
|
|
|
String flag=null;
|
|
|
if(state){
|
|
|
flag="UP";
|
|
|
}else{
|
|
|
flag="DOWN";
|
|
|
}
|
|
|
// addDbConnectionState(bean,flag);
|
|
|
return flag;
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 使用snmp协议连接Windows主机。
|
|
|
* @param bean
|
|
|
* @return
|
|
|
*/
|
|
|
private boolean contentWithJdbc(ParamterBean bean){
|
|
|
String type=bean.getType(); // 数据库类型
|
|
|
String className=null;
|
|
|
if("oracle".equalsIgnoreCase(type)){
|
|
|
className="oracle.jdbc.driver.OracleDriver";
|
|
|
}else if("mysql".equalsIgnoreCase(type)){
|
|
|
className="com.mysql.jdbc.Driver";
|
|
|
}else if("sqlServer".equalsIgnoreCase(type)){
|
|
|
className="com.microsoft.jdbc.sqlserver.SQLServerDriver";
|
|
|
}else if("db2".equalsIgnoreCase(type)){
|
|
|
className="com.ibm.db2.jcc.DB2Driver";
|
|
|
}
|
|
|
Connection conn=null;
|
|
|
String dsUser=bean.getUSER_NAME();
|
|
|
String dsPassword=bean.getPASSWORD();
|
|
|
String url=bean.getURL();
|
|
|
try {
|
|
|
Class.forName(className);
|
|
|
} catch (ClassNotFoundException e) {
|
|
|
log.error("没有找到对应的驱动程序!",e);
|
|
|
}
|
|
|
try {
|
|
|
conn= DriverManager.getConnection(url, dsUser, dsPassword);
|
|
|
} catch (SQLException e) {
|
|
|
log.error("根据用户信息,URL获取连接异常!",e);
|
|
|
}
|
|
|
boolean temp=false;
|
|
|
if(null !=conn){
|
|
|
temp=true;
|
|
|
try {
|
|
|
conn.close();
|
|
|
conn=null;
|
|
|
} catch (SQLException e) {
|
|
|
e.printStackTrace();
|
|
|
}
|
|
|
}
|
|
|
return temp;
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 使用 SSH 或 Telnet 协议 获取设备的连接结果,能连接返回 UP,否则返回 DOWN.
|
|
|
* @param bean
|
|
|
* @return
|
|
|
*/
|
|
|
public String getConnectionState4Snmp(ParamterBean bean){
|
|
|
boolean state=contentWithSnmp(bean);
|
|
|
String flag=null;
|
|
|
if(state){
|
|
|
flag="UP";
|
|
|
}else{
|
|
|
flag="DOWN";
|
|
|
}
|
|
|
return flag;
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 使用snmp协议连接Windows主机。
|
|
|
* 初始化snmp后,获取主机名称,如果能获取到的话说明能连接,否则不能连接。
|
|
|
* @param bean
|
|
|
* @return
|
|
|
*/
|
|
|
private boolean contentWithSnmp(ParamterBean bean){
|
|
|
init(bean);
|
|
|
String nameoid=".1.3.6.1.2.1.1.5.0";
|
|
|
String result = null;
|
|
|
PDU pdu = new PDU();
|
|
|
VariableBinding var = new VariableBinding(new OID(nameoid), new OctetString());
|
|
|
pdu.add(var);
|
|
|
pdu.setType(PDU.GET);
|
|
|
|
|
|
ResponseEvent res = null;
|
|
|
try {
|
|
|
res = mSnmp.send(pdu, mCommunityTarget);
|
|
|
} catch (IOException e) {
|
|
|
log.error("mSnmp.send() has error!");
|
|
|
e.printStackTrace();
|
|
|
}
|
|
|
|
|
|
PDU result_pdu = res.getResponse();
|
|
|
if (result_pdu != null) {
|
|
|
VariableBinding vb = result_pdu.get(0);
|
|
|
result = vb.getVariable().toString();
|
|
|
}
|
|
|
boolean isConnection=false;
|
|
|
if(!StringUtils.isEmpty(result)){
|
|
|
isConnection=true;
|
|
|
}
|
|
|
return isConnection;
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 初始化snmp。
|
|
|
* @param bean
|
|
|
*/
|
|
|
private void init(ParamterBean bean){
|
|
|
String ip=bean.getDEVICE_IP();
|
|
|
String communityStr=bean.getCOMMUNITY();
|
|
|
int port=bean.getPROTOCOL_PORT();
|
|
|
String addr = "udp:" + ip + "/" + port;
|
|
|
OctetString community = new OctetString(communityStr);
|
|
|
Address address = GenericAddress.parse(addr);
|
|
|
mCommunityTarget = new CommunityTarget(address, community);
|
|
|
TransportMapping vTransport = null;
|
|
|
try {
|
|
|
vTransport = new DefaultUdpTransportMapping();
|
|
|
} catch (IOException e) {
|
|
|
log.error(" create vTransport has error!",e);
|
|
|
}
|
|
|
mSnmp = new Snmp(vTransport);
|
|
|
try {
|
|
|
vTransport.listen();
|
|
|
} catch (IOException e) {
|
|
|
log.error(" vTransport.listen() has error!",e);
|
|
|
}
|
|
|
|
|
|
mCommunityTarget.setCommunity(community);
|
|
|
try {
|
|
|
mCommunityTarget.setAddress(new UdpAddress(InetAddress.getByName(ip), port));
|
|
|
} catch (UnknownHostException e) {
|
|
|
log.error(" setAddress() has error!",e);
|
|
|
}
|
|
|
mCommunityTarget.setRetries(2);
|
|
|
mCommunityTarget.setTimeout(5000);
|
|
|
mCommunityTarget.setVersion(SnmpConstants.version2c);
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 使用 SSH 或 Telnet 协议 获取设备的连接结果,能连接返回 UP,否则返回 DOWN.
|
|
|
* @param bean
|
|
|
* @return
|
|
|
*/
|
|
|
public String getConnectionState4SshOrTelnet(ParamterBean bean){
|
|
|
boolean sshState=contentWithSsh(bean);
|
|
|
String flag=null;
|
|
|
if(sshState){
|
|
|
flag="UP";
|
|
|
}else{
|
|
|
flag="DOWN";
|
|
|
}
|
|
|
return flag;
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 进行ssh连接,判断是否可以连接成功。
|
|
|
* windows操作系统使用 TelnetThread类连接。 Windows的客户端需要配置并开启Telnet相关的服务。
|
|
|
* @return
|
|
|
*/
|
|
|
private boolean contentWithSsh(ParamterBean bean){
|
|
|
String protocol=bean.getPROTOCOL();
|
|
|
String ipAddr=bean.getDEVICE_IP();
|
|
|
int protocolPort=bean.getPROTOCOL_PORT();
|
|
|
String userName=bean.getUSER_NAME();
|
|
|
String password=bean.getPASSWORD();
|
|
|
boolean temp=false;
|
|
|
RomoteController tt = null;
|
|
|
log.info("execute contentWithSsh method,params is: ipAddr="+ipAddr+",protocol="+protocol+",protocolPort="+protocolPort+",userName="+userName);
|
|
|
if(loginParamterIsOk(protocol,ipAddr,protocolPort,userName,password)){
|
|
|
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();
|
|
|
if (flag){ // 认证通过
|
|
|
log.info(ipAddr+" SSH connect,Authorized result is true authorized success!");
|
|
|
temp=true;
|
|
|
}else{
|
|
|
log.info(ipAddr+" SSH connect,Authorized result is false authorized fail!");
|
|
|
}
|
|
|
}
|
|
|
return temp;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 获取ping的结果,UP 或 DOWN。
|
|
|
* 该方法负责一个采集周期内的3次ping操作。
|
|
|
* @return
|
|
|
*/
|
|
|
public String getPingState(ParamterBean bean){
|
|
|
String ipAddr =bean.getDEVICE_IP();
|
|
|
String result=null;
|
|
|
boolean flag=false;
|
|
|
if(!StringUtils.isEmpty(ipAddr)){
|
|
|
int pingErrorCount=0; // ping 不通的次数,ping3次。
|
|
|
int interval=8; // 时间间隔8秒。
|
|
|
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);
|
|
|
} catch (InterruptedException e) {
|
|
|
e.printStackTrace();
|
|
|
}
|
|
|
}
|
|
|
if(pingErrorCount == 3){
|
|
|
log.info("["+ipAddr+"] can't connect 3 times.");
|
|
|
}else{
|
|
|
flag=true;
|
|
|
log.info("["+ipAddr+"] can connect.");
|
|
|
}
|
|
|
if(flag){
|
|
|
result="UP";
|
|
|
}else{
|
|
|
result="DOWN";
|
|
|
}
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 返回ping后的结果。
|
|
|
* @param ipAddr ip 地址。
|
|
|
* @return
|
|
|
*/
|
|
|
private boolean executeCommand(String ipAddr){
|
|
|
boolean flag=false;
|
|
|
if(!StringUtils.isEmpty(ipAddr)){
|
|
|
String command = "/bin/ping -c 3 -w 3 " + ipAddr;;
|
|
|
// 执行command 命令。
|
|
|
String line = null;
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
Runtime runtime = Runtime.getRuntime();
|
|
|
Process process = null;
|
|
|
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 protocol 协议类型
|
|
|
* @param ipAddr IP地址
|
|
|
* @param protocolPort 协议端口
|
|
|
* @param userName 用户名
|
|
|
* @param password 密码
|
|
|
* @return
|
|
|
*/
|
|
|
private boolean loginParamterIsOk(String protocol,String ipAddr,int protocolPort,String userName,String password){
|
|
|
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;
|
|
|
return flag;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 插入ping结果。
|
|
|
* @param bean
|
|
|
*/
|
|
|
public void addPingConnectionState(ConnectionStateBean bean){
|
|
|
CheckConnectionDao dao=new CheckConnectionDao();
|
|
|
dao.addPingConnectionState(bean);
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 将ParamterBean与state设置到ConnectionStateBean的属性上。
|
|
|
* @param bean
|
|
|
* @param state
|
|
|
* @return
|
|
|
*/
|
|
|
public ConnectionStateBean getBean(ParamterBean bean,String state){
|
|
|
ConnectionStateBean stateBean=new ConnectionStateBean();
|
|
|
stateBean.setDEVICE_ID(UUID.randomUUID().toString());
|
|
|
stateBean.setDEVICE_IP(bean.getDEVICE_IP());
|
|
|
stateBean.setCREATE_DATE(new Date().getTime());
|
|
|
return stateBean;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 根据IP与时间获取该时间段内ping不通的次数。
|
|
|
* 按照降序查询头3条,如果3条数据状态都为down,则视为宕机。
|
|
|
* @param ip
|
|
|
* @return
|
|
|
*/
|
|
|
public List<ConnectionStateBean> getStatByParam(String ip){
|
|
|
CheckConnectionDao dao=new CheckConnectionDao();
|
|
|
HashMap<String, Object> map=new HashMap<String, Object>();
|
|
|
map.put("DEVICE_IP",ip);
|
|
|
return dao.getStatByParam(map);
|
|
|
}
|
|
|
|
|
|
public static void main(String [] args){
|
|
|
long beforeTime = 15*60*1000+500;//15.5分钟前
|
|
|
long afterTime = 30*1000;//半分钟后
|
|
|
Date now = new Date();
|
|
|
long nn=now.getTime();
|
|
|
long before = nn - beforeTime;
|
|
|
long after = nn + afterTime;
|
|
|
System.out.println(nn);
|
|
|
System.out.println(after);
|
|
|
System.out.println(before);
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
...
|
...
|
|