initial commit

This commit is contained in:
chenjinsong
2018-09-27 16:17:06 +08:00
commit 9b3c3ac5d7
215 changed files with 50034 additions and 0 deletions

View File

@@ -0,0 +1,534 @@
package com.nms.server.thread.change;
import static com.nms.server.common.Constants.WEB_SOCKET_IP;
import static com.nms.server.common.Constants.WEB_SOCKET_PORT;
import static com.nms.server.thread.socket.SocketCMD.DOWNLOAD_PLUGIN_SCRIPT;
import static com.nms.server.thread.socket.SocketCMD.SEND_PLUGIN_SCRIPT_FILE;
import java.io.File;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import com.google.common.collect.Sets;
import com.nms.server.bean.EventRecordLibrary;
import com.nms.server.bean.NodeModel;
import com.nms.server.bean.SetInfo;
import com.nms.server.common.Common;
import com.nms.server.common.Constants;
import com.nms.server.dao.CommonDao;
import com.nms.server.service.ChangeService;
import com.nms.server.service.CommonService;
import com.nms.server.util.FileUtils;
import com.nms.server.util.StringUtil;
import com.nms.server.util.socket.SSLSocketCallable;
import com.nms.server.util.socket.SocketUtils;
/**
* 下发第三方监测脚本文件
*/
public class ChangePluginScriptFile implements Runnable {
private static final Logger logger = Logger.getLogger(ChangePluginScriptFile.class);
/*
* 脚本文件临时存储目录
*/
private File pluginScriptDir;
/*
* 接收脚本文件的NC节点列表
*/
private Set<String> ncNodesIpStrSet;
/**
* 向DC管理的所有有效服务器节点发送脚本文件
*
* @param dpluginScriptDir 脚本文件临时存储目录
*/
public ChangePluginScriptFile(File pluginScriptDir) {
this.pluginScriptDir = pluginScriptDir;
}
/**
* 向指定的NC节点发送脚本文件
*
* @param pluginScriptDir 脚本文件临时存储目录
* @param ncNodesIpStrSet 待接收脚本的NC节点列表
*/
public ChangePluginScriptFile(File pluginScriptDir, Set<String> ncNodesIpStrSet) {
this.pluginScriptDir = pluginScriptDir;
this.ncNodesIpStrSet = ncNodesIpStrSet;
}
/*
* 用于统计向特定节点发送的脚本文件
*/
private Map<String, List<File>> sendRecordList = new HashMap<String, List<File>>();
/*
* 统计文件剩余发送次数用于清理DC临时脚本文件
*/
private Map<String, Integer> fileSendLastCount = new HashMap<String, Integer>();
@SuppressWarnings("unchecked")
public void run() {
CommonDao dao = null;
try {
dao = new CommonDao();
ChangeService changeService = new ChangeService(dao);
// Thread.currentThread().setName("发送监测脚本文件");
Thread.currentThread().setName("Send A Monitoring Script File");
Collection<File> files = FileUtils.listFiles(pluginScriptDir, null, false);
if (ncNodesIpStrSet == null) {
// 未指定接收的NC节点时根据检测设置确定待接收脚本的NC节点
Map<String, SetInfo> setInfoMap = new HashMap<String, SetInfo>();
List<SetInfo> setInfos = changeService.getAllSetInfo(1, 1);
for (SetInfo setInfo : setInfos) {
if("2".equals(setInfo.getIsControlStart())) {
setInfoMap.put(setInfo.getProcessIden(), setInfo);
}
}
for (File pluginFile : files) {
String processIden = pluginFile.getName().replaceAll("\\w+_(\\w+)\\.\\w+", "$1");
SetInfo setInfo = setInfoMap.get(processIden);
// 校验 变更范围的节点IP
List<NodeModel> ipNodeModelList = changeService.getNodeModelListBySetInfo(setInfo);
for (NodeModel ip : ipNodeModelList) {
// 仅向0服务器节点发送变更信息0服务器
if (ip != null && ip.getNodeIp() != null && ip.getNodeType().longValue() == 0l
&& Common.hasIpInIpSegment(ip.getNodeIp())) {
addToSendRecordList(ip.getNodeIp(), pluginFile); //
addTofileSendLastCount(pluginFile); //
}
}
}
ncNodesIpStrSet = sendRecordList.keySet();
} else {
// 已指定待接收脚本的NC节点
for (File pluginFile : files) {
for (String ip : ncNodesIpStrSet) {
addToSendRecordList(ip, pluginFile); // 统计向特定节点发送的脚本文件
addTofileSendLastCount(pluginFile); // 统计文件剩余发送次数
}
}
}
for (String ip : ncNodesIpStrSet) {
Common.runChangeRunnable(new SendPluginScriptFile(ip, sendRecordList.get(ip)));
}
// 延时清理脚本
new Thread(new DeletePluginScriptDirAfterSending()).start();
} catch (Exception e) {
logger.error("", e);
} finally {
if (dao != null) {
dao.close();
dao = null;
}
}
}
private void addTofileSendLastCount(File pluginFile) {
Integer count = fileSendLastCount.get(pluginFile.getName());
count = (count != null) ? count : 0;
fileSendLastCount.put(pluginFile.getName(), count + 1);
}
private void addToSendRecordList(String nodeIp, File pluginFile) {
if (sendRecordList.containsKey(nodeIp)) {
sendRecordList.get(nodeIp).add(pluginFile);
} else {
List<File> files = new ArrayList<File>();
files.add(pluginFile);
sendRecordList.put(nodeIp, files);
}
}
protected class SendPluginScriptFile extends SocketUtils implements Callable<Object> {
private String cmd;
private List<File> fileList;
public SendPluginScriptFile(String ip, List<File> fileList) {
super(ip, Constants.SSL_CLIENT_PORT);
this.cmd = SEND_PLUGIN_SCRIPT_FILE;
this.fileList = fileList;
}
@Override
public Object call() throws Exception {
// Thread.currentThread().setName("发送文件 To:>" + ip);
Thread.currentThread().setName("Send File To:>" + ip);
CommonDao dao = null;
try {
if(fileList == null || fileList.size()<1){
logger.info("没有脚本文件需要发送");
return null;
}
createClientSocket();
this.sendMessage(cmd);
logger.debug("cmd:> " + cmd + " 发送命令结果>> " + this.receiveMessage());
StringBuffer sb = new StringBuffer();
for (File file : fileList) {
sb.append(",").append(file.getName());
}
this.sendMessage(sb.substring(1));
this.receiveMessage();
this.bpSendFileByBath(fileList, pluginScriptDir.getCanonicalPath());
logger.debug("cmd:> " + cmd + " 发送脚本文件>> " + this.receiveMessage());
return true;
} catch (Exception e) {
String errorInfo = "Target communication:>" + ip + " create failure" + e.getMessage();
logger.error(errorInfo, e);
dao = new CommonDao();
ChangeService changeService = new ChangeService(dao);
Map<String, String> recordContent = new HashMap<String, String>();
HashSet<String> pluginFileNames = new HashSet<String>();
for (File pluginFile : fileList) {
pluginFileNames.add(pluginFile.getName());
}
String content = StringUtils.join(pluginFileNames.iterator(), "");
recordContent.put("scriptNames", content);
changeService.saveEventRecordLibrary(cmd, Common.getIpSeqIdMap().get(ip) + ""
, "S2C", JSONObject.fromObject(recordContent).toString());
return false;
} finally {
close(); // close socket
if(dao != null) {
dao.close();
dao = null;
}
// 文件剩余发送次数为0时由DeletePluginScriptDirAfterSending线程清理脚本
for (File file : fileList) {
fileSendLastCount.put(file.getName(), fileSendLastCount.get(file.getName()) - 1);
}
}
}
}
/**
* NC初始化时发送脚本文件
*
* @param ip 接收脚本的NC节点
*/
public static void sendPluginFileWhenNcInit(final String ip) {
ChangePluginScriptFile task = null;
File tempPluginDir = ChangePluginScriptFile.getNewTempPluginDirectory();
CommonDao dao = null;
List<String> prefixNameList = new ArrayList<String>();
try {
Set<String> ipList = new HashSet<String>(1);
ipList.add(ip);
task = new ChangePluginScriptFile(tempPluginDir, ipList);
dao = new CommonDao();
CommonService service = new CommonService(dao);
List<SetInfo> setInfoList = service.selectSetInfoList(1l, null, Common.getIpSeqIdMap().get(ip), null, null, 1l, null, 0l, true);
for (SetInfo setInfo : setInfoList) {
if("2".equals(setInfo.getIsControlStart())) {
String prefixName = setInfo.getCheckTypeName() + "_" + setInfo.getProcessIden() + ".";
prefixNameList.add(prefixName);
}
}
} catch (SQLException e) {
logger.error(e.getMessage(), e);
} finally {
if (dao != null) {
dao.close();
dao = null;
}
}
boolean bool = task.waitForGettingScriptFromWeb(tempPluginDir, prefixNameList);
if (bool) {
Common.service.execute(task);
} else { // 向Web请求脚本失败记录eventRecordLibrary
try {
dao = new CommonDao();
ChangeService changeService = new ChangeService(dao);
Map<String, String> recordContent = new HashMap<String, String>();
String content = StringUtils.join(prefixNameList.iterator(), "");
recordContent.put("scriptNames", content);
changeService.saveEventRecordLibrary(SEND_PLUGIN_SCRIPT_FILE, Common.getIpSeqIdMap().get(ip) + "",
"S2C", JSONObject.fromObject(recordContent).toString());
} catch (SQLException e) {
logger.error(e.getMessage(), e);
} finally {
if (dao != null) {
dao.close();
dao = null;
}
}
}
}
/**
* 解析失败暂存信息,重新发送脚本文件<br/>
*
* @param mrlList
*/
public static void sendPluginFileBaseOnEventRecord(List<EventRecordLibrary> recordList) {
if(recordList == null || recordList.isEmpty()) {
return;
}
// W2S [脚本名前缀,...]
Set<String> w2sDetecSetInfos = new HashSet<String>();
// S2C key:NC地址, value:[脚本名前缀,...]
Map<String, Set<String>> s2cDetecSetInfos = new HashMap<String, Set<String>>();
CommonDao dao = null;
try {
dao = new CommonDao();
ChangeService changeService = new ChangeService(dao);
for (EventRecordLibrary record : recordList) {
if (SEND_PLUGIN_SCRIPT_FILE.equalsIgnoreCase(record.getRecordCommand())) { // 脚本下发
Map<?, ?> map = StringUtil.getMapFromJsonObjStr(record.getRecordContent());
String recordType = record.getRecordType();
String scriptNames = (String) map.get("scriptNames");
if("W2S".equals(recordType)) {
for (String scriptName : scriptNames.split(",")) {
w2sDetecSetInfos.add(scriptName);
}
} else if("S2C".equals(recordType)) {
for (String scriptName : scriptNames.split(",")) {
String ip = Common.getNodeIpByUUID(record.getSeqId());
Set<String> scriptNameSet = s2cDetecSetInfos.get(ip);
if(scriptNameSet == null) {
scriptNameSet = new HashSet<String>();
}
scriptNameSet.add(scriptName);
s2cDetecSetInfos.put(ip, scriptNameSet);
}
}
}
changeService.deleteEventRecordByIds(record.getId() + "");
}
} catch (SQLException e) {
logger.error("Delete EventRecordLibrary", e);
}
// W2S, 向DC管理的所有有效节点发送脚本文件
if(!w2sDetecSetInfos.isEmpty()) {
File tempPluginDir = ChangePluginScriptFile.getNewTempPluginDirectory();
ChangePluginScriptFile task = new ChangePluginScriptFile(tempPluginDir);
boolean bool = task.waitForGettingScriptFromWeb(tempPluginDir, w2sDetecSetInfos);
if(bool) {
Common.service.execute(task);
} else { // 向Web请求脚本失败记录eventRecordLibrary
try {
dao = new CommonDao();
ChangeService changeService = new ChangeService(dao);
Map<String, String> recordContent = new HashMap<String, String>();
String content = StringUtils.join(w2sDetecSetInfos.iterator(), ",");
recordContent.put("scriptNames", content);
changeService.saveEventRecordLibrary(SEND_PLUGIN_SCRIPT_FILE, "",
"W2S", JSONObject.fromObject(recordContent).toString());
} catch (SQLException e) {
logger.error(e.getMessage(), e);
} finally {
if (dao != null) {
dao.close();
dao = null;
}
}
}
}
// S2C, 向指定节点发送脚本文件
Iterator<Entry<String, Set<String>>> it = s2cDetecSetInfos.entrySet().iterator();
while(it.hasNext()) {
Entry<String, Set<String>> entry = it.next();
Set<String> recvIpSet = Sets.newHashSet(entry.getKey());
File tempPluginDir = ChangePluginScriptFile.getNewTempPluginDirectory();
ChangePluginScriptFile task = new ChangePluginScriptFile(tempPluginDir, recvIpSet);
Set<String> prefixNames = entry.getValue();
boolean bool = task.waitForGettingScriptFromWeb(tempPluginDir, prefixNames);
bool = false;
if(bool) {
Common.service.execute(task);
} else { // 向Web请求脚本失败记录eventRecordLibrary
try {
dao = new CommonDao();
ChangeService changeService = new ChangeService(dao);
Map<String, String> recordContent = new HashMap<String, String>();
String content = StringUtils.join(prefixNames.iterator(), ",");
recordContent.put("scriptNames", content);
String ips = Common.getIpSeqIdMap().get(recvIpSet.iterator().next())+"";
changeService.saveEventRecordLibrary(SEND_PLUGIN_SCRIPT_FILE, ips,
"S2C", JSONObject.fromObject(recordContent).toString());
} catch (SQLException e) {
logger.error(e.getMessage(), e);
} finally {
if (dao != null) {
dao.close();
dao = null;
}
}
}
}
}
/**
* 根据脚本名称从Web获取脚本文件并等待脚本获取完成
*
* @param dir
* @param prefixNames
* @return
*/
protected Boolean waitForGettingScriptFromWeb(File dir, Collection<String> prefixNames) {
GetScriptFileFromWeb task = null;
task = this.new GetScriptFileFromWeb(dir, prefixNames);
FutureTask<Object> future = new FutureTask<Object>(task);
new Thread(future).start();
try {
Object result = future.get();
if(result == null) {
logger.debug("从Web服务器获取脚本失败脚本列表" + prefixNames);
return false;
}
return (Boolean) result;
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return false;
}
protected class GetScriptFileFromWeb extends SSLSocketCallable {
Logger logger = Logger.getLogger(GetScriptFileFromWeb.class);
private File tempPluginDir; // 脚本存储目录
private String prefixNames; // 脚本名称列表(逗号分隔)
public GetScriptFileFromWeb(File tempPluginDir, Collection<String> prefixNames) {
super(WEB_SOCKET_IP, WEB_SOCKET_PORT);
this.tempPluginDir = tempPluginDir;
if(prefixNames != null && prefixNames.size() > 0){
StringBuilder sb = new StringBuilder();
for(String s : prefixNames){
if(StringUtils.isNotBlank(s)){
sb.append(",");
sb.append(s);
}
}
if(sb.length() >0){
sb.deleteCharAt(0);
this.prefixNames = sb.toString();
}
}
}
@Override
protected Object toDo() throws Exception {
// Thread.currentThread().setName("下载第三方监测脚本文件");
Thread.currentThread().setName("Download Third Party Monitoring Script Files");
if(StringUtils.isBlank(prefixNames)){
return true;
}
this.sendMessage(DOWNLOAD_PLUGIN_SCRIPT);
this.receiveMessage();
this.sendMessage(prefixNames);
String fileName = this.receiveMessage();
// 重复请求脚本Web无对应脚本时返回为空
if(FAIL.equalsIgnoreCase(fileName) || StringUtils.isBlank(fileName)) {
logger.error("The Web server does not monitor " + prefixNames + "the corresponding script file");
return false;
} else {
this.sendMessage(SUCCESS);
this.bpReceiveFileByBath(tempPluginDir.getCanonicalPath());
logger.info("已接收脚本文件:" + Arrays.toString(tempPluginDir.list()));
return true;
}
}
}
protected class DeletePluginScriptDirAfterSending implements Runnable {
@Override
public void run() {
while (!fileSendLastCount.isEmpty()) {
Iterator<Entry<String, Integer>> iterator = fileSendLastCount.entrySet().iterator();
while (iterator.hasNext()) {
Entry<String, Integer> entry = iterator.next();
if(entry.getValue() == 0) {
iterator.remove();
}
}
try {
TimeUnit.SECONDS.sleep(2L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
FileUtils.deleteAllFiles(pluginScriptDir, true);
}
}
/**
* web向DC下发脚本或DC向web请求脚本过程中每次都创建新的临时目录<br/>
* DC向NC下发脚本完成后将删除临时目录
*
* @return
*/
public static File getNewTempPluginDirectory() {
File tempPluginDir = new File(Constants.PLUGIN_SCRIPT_FILE_DIR, System.currentTimeMillis()+"");
if (!tempPluginDir.exists()) {
tempPluginDir.mkdirs();
}
return tempPluginDir;
}
}