commit 56d71f261a8bd6031e47e2bf80867049a2aa13da Author: chenjinsong Date: Thu Sep 27 16:11:54 2018 +0800 initial commit diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..2aed731 --- /dev/null +++ b/.classpath @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..7a20122 --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + nms_client + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..7df0c38 --- /dev/null +++ b/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,4 @@ +#Thu Mar 22 17:05:34 CST 2012 +eclipse.preferences.version=1 +encoding//src/myconfig.properties=UTF-8 +encoding/=UTF-8 diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF new file mode 100644 index 0000000..5bbb78d --- /dev/null +++ b/META-INF/MANIFEST.MF @@ -0,0 +1,4 @@ +Manifest-Version: 1.0 +Class-Path: ../lib/commons-net-ftp-2.0.jar ../lib/dom4j-1.6.1.jar ../lib/json-lib-2.2.2-jdk15.jar ../lib/commons-beanutils-1.7.jar ../lib/commons-collections.jar ../lib/commons-lang.jar ../lib/commons-logging.jar ../lib/ezmorph-1.0.4.jar ../lib/log4j-1.2.15.jar ../lib/junit.jar ../lib/sigar.jar ../lib/ostermillerutils_1_07_00.jar ../lib/commons-io.jar ../lib/ant.jar ../lib/javatar-2.5.jar ../lib/java-unrar-0.3.jar +Main-Class: com.nis.nmsclient.NmsClient + diff --git a/META-INF/readme.txt b/META-INF/readme.txt new file mode 100644 index 0000000..fab20ae --- /dev/null +++ b/META-INF/readme.txt @@ -0,0 +1,12 @@ +WEB布署说明: + +1、Windows下: 在Tomcat目录下的bin中相应的添加sigar-x86-winnt.dll或sigar-amd64-winnt.dll + +2、Linux下:加载动态库(.so),在配置文件~/.bash_profile或者/etc/profile中添加变量 + LD_LIBRARY_PATH = (相应配置libsigar-x86-linux.so或libsigar-amd64-linux.so的存放目录),执行source ./bash_profile或/etc/profile + + + +JAVA应用程序布署说明: +1、打nmsclient.jar,并使用MANIFEST.MF配置主函数入口(Main-Class),和需要用到的jar包(Class-Path),jar包路径是相对nmsclient.jar的位置。 +2、Windows下: 相应放sigar-x86-winnt.dll或sigar-amd64-winnt.dll在jdk/bin下。 \ No newline at end of file diff --git a/bin/log4j.properties.svntmp b/bin/log4j.properties.svntmp new file mode 100644 index 0000000..c5aa4c7 --- /dev/null +++ b/bin/log4j.properties.svntmp @@ -0,0 +1,15 @@ +log4j.rootLogger = debug,stdout,logfile + +log4j.appender.stdout = org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout.ConversionPattern = %d %p [%c] [%t] - <%m>%n +log4j.appender.stdout.layout = org.apache.log4j.PatternLayout + +#----------------------debug--------------------- + +log4j.appender.logfile = org.apache.log4j.RollingFileAppender +log4j.appender.logfile.MaxFileSize = 50MB +log4j.appender.logfile.MaxBackupIndex = 20 + +log4j.appender.logfile.File = ./nc_logs/nmsclient.log +log4j.appender.logfile.layout.ConversionPattern = %d %p [%c] [%t] - <%m>%n +log4j.appender.logfile.layout = org.apache.log4j.PatternLayout diff --git a/lib/commons-beanutils-1.7.jar b/lib/commons-beanutils-1.7.jar new file mode 100644 index 0000000..b1b89c9 Binary files /dev/null and b/lib/commons-beanutils-1.7.jar differ diff --git a/lib/commons-collections.jar b/lib/commons-collections.jar new file mode 100644 index 0000000..75580be Binary files /dev/null and b/lib/commons-collections.jar differ diff --git a/lib/commons-io.jar b/lib/commons-io.jar new file mode 100644 index 0000000..7affdef Binary files /dev/null and b/lib/commons-io.jar differ diff --git a/lib/commons-lang.jar b/lib/commons-lang.jar new file mode 100644 index 0000000..b910561 Binary files /dev/null and b/lib/commons-lang.jar differ diff --git a/lib/commons-logging.jar b/lib/commons-logging.jar new file mode 100644 index 0000000..8758a96 Binary files /dev/null and b/lib/commons-logging.jar differ diff --git a/lib/ezmorph-1.0.4.jar b/lib/ezmorph-1.0.4.jar new file mode 100644 index 0000000..7625af6 Binary files /dev/null and b/lib/ezmorph-1.0.4.jar differ diff --git a/lib/fileComment.jar b/lib/fileComment.jar new file mode 100644 index 0000000..8c251d9 Binary files /dev/null and b/lib/fileComment.jar differ diff --git a/lib/filemgr/ant.jar b/lib/filemgr/ant.jar new file mode 100644 index 0000000..0a56a58 Binary files /dev/null and b/lib/filemgr/ant.jar differ diff --git a/lib/filemgr/java-unrar-0.3.jar b/lib/filemgr/java-unrar-0.3.jar new file mode 100644 index 0000000..48bebc9 Binary files /dev/null and b/lib/filemgr/java-unrar-0.3.jar differ diff --git a/lib/filemgr/javatar-2.5.jar b/lib/filemgr/javatar-2.5.jar new file mode 100644 index 0000000..0d4def6 Binary files /dev/null and b/lib/filemgr/javatar-2.5.jar differ diff --git a/lib/json-lib-2.2.2-jdk15.jar b/lib/json-lib-2.2.2-jdk15.jar new file mode 100644 index 0000000..27e7c7c Binary files /dev/null and b/lib/json-lib-2.2.2-jdk15.jar differ diff --git a/lib/junit.jar b/lib/junit.jar new file mode 100644 index 0000000..674d71e Binary files /dev/null and b/lib/junit.jar differ diff --git a/lib/log4j-1.2.15.jar b/lib/log4j-1.2.15.jar new file mode 100644 index 0000000..c930a6a Binary files /dev/null and b/lib/log4j-1.2.15.jar differ diff --git a/lib/ostermillerutils_1_07_00.jar b/lib/ostermillerutils_1_07_00.jar new file mode 100644 index 0000000..a993150 Binary files /dev/null and b/lib/ostermillerutils_1_07_00.jar differ diff --git a/lib/sigar/.sigar_shellrc b/lib/sigar/.sigar_shellrc new file mode 100644 index 0000000..ed12204 --- /dev/null +++ b/lib/sigar/.sigar_shellrc @@ -0,0 +1,48 @@ +#this file is loaded by the sigar shell. +#commands in this file are run just as they would be if they +#were typed in by hand in the shell prompt. + +#find weblogic nodes (-1 means last index in the array) +alias ps-wls ps State.Name.eq=java,Args.-1.eq=weblogic.Server + +#find websphere 4.x nodes +alias ps-was4 ps State.Name.eq=java,Args.*.eq=com.ibm.ejs.sm.server.ManagedServer + +#find websphere admin server +alias ps-was4adm ps State.Name.eq=java,Args.*.eq=com.ibm.ejs.sm.server.AdminServer + +#find websphere 5.x nodes +alias ps-was5 ps State.Name.eq=java,Args.*.eq=com.ibm.ws.runtime.WsServer + +#find websphere 4.x and 5.x nodes +alias ps-was ps State.Name.eq=java,Args.*.eq=com.ibm.ws.bootstrap.WSLauncher + +#find jboss (use .sw=java to match 'java' or 'javaw') +alias ps-jboss ps State.Name.sw=java,Args.*.eq=org.jboss.Main + +#find tomcat +alias ps-tomcat ps State.Name.eq=java,Args.*.eq=org.apache.catalina.startup.Bootstrap + +#find apache parent processes +#($1 is the return value of the first query in the string) +#'Pne' => 'P' flags means parent of matched process +#to filter out httpd child processes +alias ps-apache ps State.Name.re=https?d.*|[Aa]pache2?$,State.Name.Pne=$1 + +#find ant processes (ant hangs on me sometimes) +#(* matches any value in the array) +alias ps-ant ps State.Name.eq=java,Args.*.eq=org.apache.tools.ant.Main + +#HQ agents +alias ps-hqagent ps State.Name.sw=java,Args.-1.eq=org.hyperic.hq.agent.server.AgentDaemon + +#find all java procs except the shell itself +#($$ is the current process id) +alias ps-java ps State.Name.eq=java,Pid.Pid.ne=$$ +alias java ps-java + +#find all processes owned by the current user +alias ps-me ps CredName.User.eq=$user.name + +#VMware Server or GSX VMs +alias ps-vmx ps State.Name.eq=vmware-vmx,Args.1.eq=-C diff --git a/lib/sigar/libsigar-amd64-freebsd-6.so b/lib/sigar/libsigar-amd64-freebsd-6.so new file mode 100644 index 0000000..9ec33a9 Binary files /dev/null and b/lib/sigar/libsigar-amd64-freebsd-6.so differ diff --git a/lib/sigar/libsigar-amd64-linux.so b/lib/sigar/libsigar-amd64-linux.so new file mode 100644 index 0000000..913f325 Binary files /dev/null and b/lib/sigar/libsigar-amd64-linux.so differ diff --git a/lib/sigar/libsigar-amd64-solaris.so b/lib/sigar/libsigar-amd64-solaris.so new file mode 100644 index 0000000..ae9a4f1 Binary files /dev/null and b/lib/sigar/libsigar-amd64-solaris.so differ diff --git a/lib/sigar/libsigar-ia64-hpux-11.sl b/lib/sigar/libsigar-ia64-hpux-11.sl new file mode 100644 index 0000000..1dc74db Binary files /dev/null and b/lib/sigar/libsigar-ia64-hpux-11.sl differ diff --git a/lib/sigar/libsigar-ia64-linux.so b/lib/sigar/libsigar-ia64-linux.so new file mode 100644 index 0000000..2bd2fc8 Binary files /dev/null and b/lib/sigar/libsigar-ia64-linux.so differ diff --git a/lib/sigar/libsigar-pa-hpux-11.sl b/lib/sigar/libsigar-pa-hpux-11.sl new file mode 100644 index 0000000..c63eb22 Binary files /dev/null and b/lib/sigar/libsigar-pa-hpux-11.sl differ diff --git a/lib/sigar/libsigar-ppc-aix-5.so b/lib/sigar/libsigar-ppc-aix-5.so new file mode 100644 index 0000000..480c440 Binary files /dev/null and b/lib/sigar/libsigar-ppc-aix-5.so differ diff --git a/lib/sigar/libsigar-ppc-linux.so b/lib/sigar/libsigar-ppc-linux.so new file mode 100644 index 0000000..d5637a7 Binary files /dev/null and b/lib/sigar/libsigar-ppc-linux.so differ diff --git a/lib/sigar/libsigar-ppc64-aix-5.so b/lib/sigar/libsigar-ppc64-aix-5.so new file mode 100644 index 0000000..9a3a737 Binary files /dev/null and b/lib/sigar/libsigar-ppc64-aix-5.so differ diff --git a/lib/sigar/libsigar-ppc64-linux.so b/lib/sigar/libsigar-ppc64-linux.so new file mode 100644 index 0000000..4875241 Binary files /dev/null and b/lib/sigar/libsigar-ppc64-linux.so differ diff --git a/lib/sigar/libsigar-s390x-linux.so b/lib/sigar/libsigar-s390x-linux.so new file mode 100644 index 0000000..ae8ac4b Binary files /dev/null and b/lib/sigar/libsigar-s390x-linux.so differ diff --git a/lib/sigar/libsigar-sparc-solaris.so b/lib/sigar/libsigar-sparc-solaris.so new file mode 100644 index 0000000..507effe Binary files /dev/null and b/lib/sigar/libsigar-sparc-solaris.so differ diff --git a/lib/sigar/libsigar-sparc64-solaris.so b/lib/sigar/libsigar-sparc64-solaris.so new file mode 100644 index 0000000..1a4bc18 Binary files /dev/null and b/lib/sigar/libsigar-sparc64-solaris.so differ diff --git a/lib/sigar/libsigar-universal-macosx.dylib b/lib/sigar/libsigar-universal-macosx.dylib new file mode 100644 index 0000000..4a35824 Binary files /dev/null and b/lib/sigar/libsigar-universal-macosx.dylib differ diff --git a/lib/sigar/libsigar-universal64-macosx.dylib b/lib/sigar/libsigar-universal64-macosx.dylib new file mode 100644 index 0000000..dc27122 Binary files /dev/null and b/lib/sigar/libsigar-universal64-macosx.dylib differ diff --git a/lib/sigar/libsigar-x86-freebsd-5.so b/lib/sigar/libsigar-x86-freebsd-5.so new file mode 100644 index 0000000..67de5df Binary files /dev/null and b/lib/sigar/libsigar-x86-freebsd-5.so differ diff --git a/lib/sigar/libsigar-x86-freebsd-6.so b/lib/sigar/libsigar-x86-freebsd-6.so new file mode 100644 index 0000000..7b3a264 Binary files /dev/null and b/lib/sigar/libsigar-x86-freebsd-6.so differ diff --git a/lib/sigar/libsigar-x86-linux.so b/lib/sigar/libsigar-x86-linux.so new file mode 100644 index 0000000..46df73a Binary files /dev/null and b/lib/sigar/libsigar-x86-linux.so differ diff --git a/lib/sigar/libsigar-x86-solaris.so b/lib/sigar/libsigar-x86-solaris.so new file mode 100644 index 0000000..ea33591 Binary files /dev/null and b/lib/sigar/libsigar-x86-solaris.so differ diff --git a/lib/sigar/libsigar-x86_64-linux.so b/lib/sigar/libsigar-x86_64-linux.so new file mode 100644 index 0000000..913f325 Binary files /dev/null and b/lib/sigar/libsigar-x86_64-linux.so differ diff --git a/lib/sigar/sigar-amd64-winnt.dll b/lib/sigar/sigar-amd64-winnt.dll new file mode 100644 index 0000000..0d2977f Binary files /dev/null and b/lib/sigar/sigar-amd64-winnt.dll differ diff --git a/lib/sigar/sigar-x86-winnt.dll b/lib/sigar/sigar-x86-winnt.dll new file mode 100644 index 0000000..7b29a4e Binary files /dev/null and b/lib/sigar/sigar-x86-winnt.dll differ diff --git a/lib/sigar/sigar-x86-winnt.lib b/lib/sigar/sigar-x86-winnt.lib new file mode 100644 index 0000000..928b2c7 Binary files /dev/null and b/lib/sigar/sigar-x86-winnt.lib differ diff --git a/lib/sigar/sigar.jar b/lib/sigar/sigar.jar new file mode 100644 index 0000000..8fe8400 Binary files /dev/null and b/lib/sigar/sigar.jar differ diff --git a/linuxinstall/autoinstall.sh b/linuxinstall/autoinstall.sh new file mode 100644 index 0000000..ce83980 --- /dev/null +++ b/linuxinstall/autoinstall.sh @@ -0,0 +1,170 @@ +#!/bin/bash + +# --- set default value +DEFAULT_DATA_DIR="/home/nms/nmsdata" +DEFAULT_INSTALL_DIR="/home/nms/nmsclient" + +# --- set install dir +PRG="$0" +PRGDIR=`dirname "$PRG"` +CUR_PRGDIR=`cd "$PRGDIR"; pwd` + +INSTALL_DIR="$DEFAULT_INSTALL_DIR" + +if [ ! -d $INSTALL_DIR ] + then + mkdir -p $INSTALL_DIR +fi + +INSTALL_DIR=`cd "$INSTALL_DIR"; pwd` + +# --- check jdk and jdk-version +install_jdk=0 +javaversion=`java -version 2>&1|grep "java version"` +if [ -n "$javaversion" ] + then + # javaversion=${javaversion:14:3} + javavmajor=`echo $javaversion | cut -c15` + javavminor=`echo $javaversion | cut -c17` +# OS_TYPE=$( lsb_release -d| cut -d: -f2| cut -f2 ) +# if [ "`echo $OS_TYPE | cut -c1-6`" = "Ubuntu" ] +# then +# if [ 2 -gt $javavmajor ]; then +# if [ 6 -gt $javavminor ]; then +# install_jdk=1 +# fi +# fi +# else + if [[ 2 -gt $javavmajor && 6 -gt $javavminor ]]; then + install_jdk=1 + fi +# fi + else + install_jdk=1 +fi + +# --- install jdk +cd "$INSTALL_DIR"/.. +NMS_JDK="$(pwd)/nmsjdk" +JDK_DIR="$(pwd)/jdk1.7.0_80" +JDK_BIN_FILE=$CUR_PRGDIR"/jre_install/jdk-7u80-linux-i586.tar.gz" +if [ "`uname -i`" = "x86_64" ];then + JDK_BIN_FILE=$CUR_PRGDIR"/jre_install/jdk-7u80-linux-x64.tar.gz" +fi +if [ $install_jdk = 1 ] + then + if [ ! -e "$NMS_JDK" ] + then + echo "JDK bin file: $JDK_BIN_FILE" + echo "now, install jdk: $NMS_JDK" + sleep 3 + + if [ ! -e "$JDK_DIR" ];then + mkdir -p $JDK_DIR + fi + tar -xzf $JDK_BIN_FILE -C $JDK_DIR --strip-components=1 || installJdk=1 + if [ -n "$installJdk" ];then + echo "install jdk failure, exit program" + exit 1 + fi + ln -s $JDK_DIR $NMS_JDK + echo "install jdk done" + fi +elif [ -n "$JAVA_HOME" ];then + ln -s $JAVA_HOME $NMS_JDK +else + echo "JDK bin file: $JDK_BIN_FILE" + echo "now, install jdk: $NMS_JDK" + sleep 3 + if [ ! -e "$JDK_DIR" ];then + mkdir -p $JDK_DIR + fi + tar -xzf $JDK_BIN_FILE -C $JDK_DIR --strip-components=1 || installJdk=1 + if [ -n "$installJdk" ];then + echo "install jdk failure, exit program" + exit 1 + fi + ln -s $JDK_DIR $NMS_JDK + echo "install jdk done" +fi +cd "$CUR_PRGDIR" + +echo "===========================================" +echo "NMS_JDK: $NMS_JDK" +echo "INSTALL_DIR: $INSTALL_DIR" +echo "===========================================" + +# --- copy file to install_dir +if [ "$INSTALL_DIR" != "$CUR_PRGDIR" ];then + CP_DIR=( + bin + lib + conf + shell + ) + #cp + for CP_NAME in ${CP_DIR[@]} + do + cp -a $CUR_PRGDIR"/$CP_NAME" $INSTALL_DIR + done +fi + + +function modify_file(){ + if [ $# != 2 ] + then + echo "usage: modify_file [prop_name] [prop_value]" + exit 0 + fi + prop_name="$1" + prop_value="$2" + #echo "modify_file $prop_name $prop_value" + if [ -z "$(cat $PROP_FILE |grep $prop_name)" ] + then + echo "" >> $PROP_FILE + echo "$prop_name=$prop_value" >> $PROP_FILE + else + sed -i "s@^$prop_name.*@$prop_name=$prop_value@" $PROP_FILE + fi +} + +# --- modify property +#-------------file path +path="$DEFAULT_DATA_DIR" +#-------------include path +include_path="$INSTALL_DIR,$path" +#-------------exclude path +exclude_path="$INSTALL_DIR/bin,$INSTALL_DIR/lib,$INSTALL_DIR/shell,$INSTALL_DIR/conf" +#-------------log4j dir +logs_path="$path/nc_logs" + +PROP_FILE=$INSTALL_DIR"/conf/myconfig.properties" +#echo "PROP_FILE: $PROP_FILE" +modify_file "local.data.path" $path +modify_file "common.del.path.include" $include_path +modify_file "common.del.path.exclude" $exclude_path + +# modify log4j +PROP_FILE=$INSTALL_DIR"/conf/log4j.properties" +encoding=${LANG#*.} +modify_file "log4j.appender.stdout.encoding" $encoding +modify_file "log4j.appender.debugAppender.encoding" $encoding +modify_file "log4j.appender.infoAppender.encoding" $encoding +modify_file "log4j.appender.debugAppender.File" "$logs_path/nmsclient_debug.log" +modify_file "log4j.appender.infoAppender.File" "$logs_path/nmsclient_info.log" + +#permit +cd $INSTALL_DIR"/shell" +chmod 755 *.sh +cd $CUR_PRGDIR + +if [ -z "$(cat /etc/rc.local|grep $INSTALL_DIR"/shell/startup.sh")" ] +then + echo $INSTALL_DIR"/shell/startup.sh" >> /etc/rc.local +fi + +echo "" +echo "install successed..." +echo "please use [$INSTALL_DIR/shell/startup.sh] to run the program..." + +$INSTALL_DIR/shell/startup.sh diff --git a/linuxinstall/conf/jvm.conf b/linuxinstall/conf/jvm.conf new file mode 100644 index 0000000..f4edf37 --- /dev/null +++ b/linuxinstall/conf/jvm.conf @@ -0,0 +1,2 @@ +-Xms64m +-Xmx128m \ No newline at end of file diff --git a/linuxinstall/detectShell/config b/linuxinstall/detectShell/config new file mode 100644 index 0000000..5b2757e --- /dev/null +++ b/linuxinstall/detectShell/config @@ -0,0 +1,5 @@ +configPath=/home/nms/nmsdata/nc_config +sysinfoPath=/root/zhong/sysinfo +ip1=192.168.11.211 +ip2=192.168.11.211 +ip3=192.168.11.211 diff --git a/linuxinstall/detectShell/getMacInfo.v2.sh b/linuxinstall/detectShell/getMacInfo.v2.sh new file mode 100644 index 0000000..6b32b8e --- /dev/null +++ b/linuxinstall/detectShell/getMacInfo.v2.sh @@ -0,0 +1,590 @@ +#!/bin/bash + +basePath=$(cd `dirname $0`; pwd) +date=`date +%Y%m%d%H%M%S` +d=`date "+%Y-%m-%d %H:%M:%S"` #temp column +t=`date -d "$d" +%s` #temp column +t2=`date "+%N" | awk '{print int($0)}'` +dateStamp=$((t*1000+t2/1000000)) #current time stamp +sep=\$@\$ + +cd ${basePath} +while read line;do # 读取config + eval "$line" +done < config + +if [ ! -d macInfo ] + then + mkdir macInfo +fi + +if [ ! -d result ] + then + mkdir result +fi + +if [ ! -f firstTimeDate ] + then + touch firstTimeDate + echo ${dateStamp} > firstTimeDate + firstTimeDate=${dateStamp} + else + firstTimeDate=`cat firstTimeDate` +fi + +# 读取任务配置文件 +OLD_IFS="$IFS" +IFS="," + +cpu_pubInfo=`cat ${configPath}/cpu_cpu.cfg | grep pubInfo | awk -F'=' '{print $2}'` +cpu_checkState=`cat ${configPath}/cpu_cpu.cfg | grep checkState | awk -F'=' '{print $2}'` +cpu_checkGap=`cat ${configPath}/cpu_cpu.cfg | grep checkGap | awk -F'=' '{print $2}'` +cpu_checkOutTime=`cat ${configPath}/cpu_cpu.cfg | grep checkOutTime | awk -F'=' '{print $2}'` +cpu_checkMaxTimes=`cat ${configPath}/cpu_cpu.cfg | grep checkMaxTimes | awk -F'=' '{print $2}'` +cpu_planCheckTime=`cat ${configPath}/cpu_cpu.cfg | grep planCheckTime | awk -F'=' '{print $2}'` +cpu_uploadGap=`cat ${configPath}/cpu_cpu.cfg | grep uploadGap | awk -F'=' '{print $2}'` +cpu_dataFileDir=`cat ${configPath}/cpu_cpu.cfg | grep dataFileDir | awk -F'=' '{print $2}'` +cpu_polices=`cat ${configPath}/cpu_cpu.cfg | grep police | awk -F'=' '{print $2}'` +cpu_polices_arr=($cpu_polices) +cpu_police_flag=0 +cpu_nextDateStamp=$((cpu_checkGap*60*1000+dateStamp)) +mem_pubInfo=`cat ${configPath}/memory_memory.cfg | grep pubInfo | awk -F'=' '{print $2}'` +mem_checkState=`cat ${configPath}/memory_memory.cfg | grep checkState | awk -F'=' '{print $2}'` +mem_checkGap=`cat ${configPath}/memory_memory.cfg | grep checkGap | awk -F'=' '{print $2}'` +mem_checkOutTime=`cat ${configPath}/memory_memory.cfg | grep checkOutTime | awk -F'=' '{print $2}'` +mem_checkMaxTimes=`cat ${configPath}/memory_memory.cfg | grep checkMaxTimes | awk -F'=' '{print $2}'` +mem_planCheckTime=`cat ${configPath}/memory_memory.cfg | grep planCheckTime | awk -F'=' '{print $2}'` +mem_uploadGap=`cat ${configPath}/memory_memory.cfg | grep uploadGap | awk -F'=' '{print $2}'` +mem_dataFileDir=`cat ${configPath}/memory_memory.cfg | grep dataFileDir | awk -F'=' '{print $2}'` +mem_polices=`cat ${configPath}/memory_memory.cfg | grep police | awk -F'=' '{print $2}'` +mem_polices_arr=($mem_polices) +mem_police_flag=0 +mem_nextDateStamp=$((mem_checkGap*60*1000+dateStamp)) +disk_pubInfo=`cat ${configPath}/disk_disk.cfg | grep pubInfo | awk -F'=' '{print $2}'` +disk_checkState=`cat ${configPath}/disk_disk.cfg | grep checkState | awk -F'=' '{print $2}'` +disk_checkGap=`cat ${configPath}/disk_disk.cfg | grep checkGap | awk -F'=' '{print $2}'` +disk_checkOutTime=`cat ${configPath}/disk_disk.cfg | grep checkOutTime | awk -F'=' '{print $2}'` +disk_checkMaxTimes=`cat ${configPath}/disk_disk.cfg | grep checkMaxTimes | awk -F'=' '{print $2}'` +disk_planCheckTime=`cat ${configPath}/disk_disk.cfg | grep planCheckTime | awk -F'=' '{print $2}'` +disk_uploadGap=`cat ${configPath}/disk_disk.cfg | grep uploadGap | awk -F'=' '{print $2}'` +disk_dataFileDir=`cat ${configPath}/disk_disk.cfg | grep dataFileDir | awk -F'=' '{print $2}'` +disk_polices=`cat ${configPath}/disk_disk.cfg | grep police | awk -F'=' '{print $2}'` +disk_polices_arr=($disk_polices) +disk_police_flag=0 +disk_nextDateStamp=$((disk_checkGap*60*1000+dateStamp)) +net_pubInfo=`cat ${configPath}/net_net.cfg | grep pubInfo | awk -F'=' '{print $2}'` +net_checkState=`cat ${configPath}/net_net.cfg | grep checkState | awk -F'=' '{print $2}'` +net_checkGap=`cat ${configPath}/net_net.cfg | grep checkGap | awk -F'=' '{print $2}'` +net_checkOutTime=`cat ${configPath}/net_net.cfg | grep checkOutTime | awk -F'=' '{print $2}'` +net_checkMaxTimes=`cat ${configPath}/net_net.cfg | grep checkMaxTimes | awk -F'=' '{print $2}'` +net_planCheckTime=`cat ${configPath}/net_net.cfg | grep planCheckTime | awk -F'=' '{print $2}'` +net_uploadGap=`cat ${configPath}/net_net.cfg | grep uploadGap | awk -F'=' '{print $2}'` +net_dataFileDir=`cat ${configPath}/net_net.cfg | grep dataFileDir | awk -F'=' '{print $2}'` +net_polices=`cat ${configPath}/net_net.cfg | grep police | awk -F'=' '{print $2}'` +net_polices_arr=($net_polices) +net_police_flag=0 +net_nextDateStamp=$((net_checkGap*60*1000+dateStamp)) +sys_pubInfo=`cat ${configPath}/systeminfo_servicessysinfo.cfg | grep pubInfo | awk -F'=' '{print $2}'` +sys_checkState=`cat ${configPath}/systeminfo_servicessysinfo.cfg | grep checkState | awk -F'=' '{print $2}'` +sys_checkGap=`cat ${configPath}/systeminfo_servicessysinfo.cfg | grep checkGap | awk -F'=' '{print $2}'` +sys_checkOutTime=`cat ${configPath}/systeminfo_servicessysinfo.cfg | grep checkOutTime | awk -F'=' '{print $2}'` +sys_checkMaxTimes=`cat ${configPath}/systeminfo_servicessysinfo.cfg | grep checkMaxTimes | awk -F'=' '{print $2}'` +sys_planCheckTime=`cat ${configPath}/systeminfo_servicessysinfo.cfg | grep planCheckTime | awk -F'=' '{print $2}'` +sys_uploadGap=`cat ${configPath}/systeminfo_servicessysinfo.cfg | grep uploadGap | awk -F'=' '{print $2}'` +sys_dataFileDir=`cat ${configPath}/systeminfo_servicessysinfo.cfg | grep dataFileDir | awk -F'=' '{print $2}'` +sys_polices=`cat ${configPath}/systeminfo_servicessysinfo.cfg | grep police | awk -F'=' '{print $2}'` +sys_polices_arr=($sys_polices) +sys_police_flag=0 +sys_nextDateStamp=$((sys_checkGap*60*1000+dateStamp)) + +IFS="$OLD_IFS" + +sysinfoSrc=`cat ${sysinfoPath}` + +## begin content weaving ## +# task info +cpuResult_taskInfo=${cpu_pubInfo}","${firstTimeDate}","${cpu_checkOutTime}","${dateStamp}",1,"${cpu_nextDateStamp}"," +memResult_taskInfo=${mem_pubInfo}","${firstTimeDate}","${mem_checkOutTime}","${dateStamp}",1,"${mem_nextDateStamp}"," +diskResult_taskInfo=${disk_pubInfo}","${firstTimeDate}","${disk_checkOutTime}","${dateStamp}",1,"${disk_nextDateStamp}"," +netResult_taskInfo=${net_pubInfo}","${firstTimeDate}","${net_checkOutTime}","${dateStamp}",1,"${net_nextDateStamp}"," +sysResult_taskInfo=${sys_pubInfo}","${firstTimeDate}","${sys_checkOutTime}","${dateStamp}",1,"${sys_nextDateStamp}",1," + +cpuResult_coreNum=0 +disk_total_num=0 +net_total_num=0 +sys_net_total_num=0 +diskResult_baseInfo="\"" +memResult_baseInfo="\"" +netResult_baseInfo="\"" +sysResult_baseInfo="\"" +# result file + +cpuResult=result/cpuResult_${date} +memResult=result/memResult_${date} +diskResult=result/diskResult_${date} +netResult=result/netResult_${date} +sysResult=result/sysResult_${date} + +function getDetail { + cpuInfo=macInfo/$1_cpuInfo_${date} + memInfo=macInfo/$1_memInfo_${date} + diskInfo=macInfo/$1_diskInfo_${date} + netInfo=macInfo/$1_netInfo_${date} + sysInfo=macInfo/$1_sysInfo_${date} + + ssh -tt $2 "sar -P ALL 1 1" > ${cpuInfo} + ssh -tt $2 "cat /proc/cpuinfo | grep MHz" > ${cpuInfo}2 + ssh -tt $2 "free|awk 'NR>1{print}'" > ${memInfo} + ssh -tt $2 "df -l|grep -v tmpfs|awk 'NR>1{print}'" > ${diskInfo} + + # 网卡信息 + special_net_result_t=`ssh -C $2 "/bin/bash" < remote_net.sh` # 获取特殊网卡信息 + special_net_result_base=${special_net_result_t%details,*} + special_net_result_details_t=${special_net_result_t#*details,} + special_net_result_details="\""${special_net_result_details_t#*\"} + special_net_result_details_t_arr=($special_net_result_details_t) + special_net_result_detailsNum=${special_net_result_details_t_arr[0]} + special_net_result=${special_net_result_base}"details,"${special_net_result_detailsNum}$'\n' + for((i=1;i<${#special_net_result_details_t_arr[@]};i++));do + special_net_result=${special_net_result}${special_net_result_details_t_arr[$i]}$'\n' + done + echo "$special_net_result" > ${netInfo}3 + getNetInfo + + dos2unix ${cpuInfo} > /dev/null 2>&1 + dos2unix ${cpuInfo}2 > /dev/null 2>&1 + dos2unix ${memInfo} > /dev/null 2>&1 + dos2unix ${diskInfo} > /dev/null 2>&1 + #dos2unix ${diskInfo} > /dev/null 2>&1 + + # cpu info + cpu_t=`awk -F "(" '{print $3}' ${cpuInfo}` # temp column + + cpu_coreNum=`echo $cpu_t|awk -F " " '{print $1}'` + cpuResult_coreNum=$((cpuResult_coreNum+cpu_coreNum)) + cpu_totalMHz=`awk '{total+=$4}END{print total}' ${cpuInfo}2` + cpu_averMHz=`echo "scale=2;$cpu_totalMHz/$cpu_coreNum"|bc|awk '{printf "%.2f",$0}'` + cpu_idle_total=`awk 'NR==4{print $9}' ${cpuInfo}` + cpu_shiyonglv=`bc <<<100-$cpu_idle_total|awk '{printf "%.2f",$0}'` + + cpuResult_baseInfo=${cpuResult_baseInfo}${sep}"cpu${index} i18n_client.SystemInfo.mhz_n81i"${cpu_averMHz}"MHz,i18n_client.SystemInfo.shiyonglv_n81i "${cpu_shiyonglv}"%; " + getCpuBase2 ${cpuInfo} ${cpuInfo}2 + getCpuDetail ${cpuInfo} ${cpuInfo}2 + + # mem info + swap_total_t=`cat ${memInfo}|grep '^S'|awk '{print $2}'` + swap_total=`echo "scale=2;${swap_total_t}/1024/1024"|bc|awk '{printf "%.2f",$0}'` + swap_free_t=`cat ${memInfo}|grep '^S'|awk '{print $4}'` + swap_free=`echo "scale=2;${swap_free_t}/1024/1024"|bc|awk '{printf "%.2f",$0}'` + mem_total_t=`awk 'NR==1{print $2}' ${memInfo}` + mem_total=`echo "scale=2;${mem_total_t}/1024/1024"|bc|awk '{printf "%.2f",$0}'` + mem_used_t=`awk 'NR==1{print $3}' ${memInfo}` + mem_used=`echo "scale=2;${mem_used_t}/1024/1024"|bc|awk '{printf "%.2f",$0}'` + mem_free=`echo "${mem_total}-${mem_used}"|bc|awk '{printf "%.2f",$0}'` + mem_shiyonglv=`echo "scale=2;${mem_used}/${mem_total}*100.00"|bc|awk '{printf "%.2f",$0}'` + memResult_baseInfo="${memResult_baseInfo}"${sep}"i18n_client.SystemInfo.memerySize_n81i: "${mem_total}"G, i18n_client.SystemInfo.currentUsed_n81i:"${mem_used}"G, i18n_client.SystemInfo.spaceRemain_n81i:"${mem_free}"G, i18n_client.SystemInfo.shiyonglv_n81i:"${mem_shiyonglv}"% " + mem_detail_nopolice=${swap_total}","${swap_free}","${mem_total}","${mem_used}","${mem_free}","${mem_shiyonglv}","$'\n' + OLD_IFS="$IFS" + IFS="," + mem_detail_nopolice_arr=(${mem_detail_nopolice}) + IFS=$OLD_IFS + # police + if [ ! -z $mem_polices ] + then + mem_police_most_level=0 + mem_police_flag_t=0 #临时变量 + mem_baseInfo_police="" + for((j=0;j<${#mem_polices_arr[@]};j++));do + mem_detail_police_t="" + OLD_IFS="$IFS" + IFS="|" + mem_police_arr=(${mem_polices_arr[$j]}) + IFS=$OLD_IFS + + if (($(echo "${mem_detail_nopolice_arr[((${mem_police_arr[0]}-1))]} ${mem_police_arr[1]} ${mem_police_arr[2]}"|bc) == 1)) + then #触发告警 + mem_detail_police_t=${mem_police_arr[0]}","${mem_police_arr[3]}","${mem_police_arr[2]}"," + mem_police_flag=1 + mem_police_flag_t=1 + if ((${mem_police_arr[3]} > ${mem_police_most_level})) + then + mem_police_most_level=${mem_police_arr[3]} + mem_detail_police=$mem_detail_police_t + mem_baseInfo_police="【${mem_detail_nopolice_arr[0]}】"${mem_police_arr[4]}${mem_detail_nopolice_arr[((${mem_police_arr[0]}-1))]}"% i18n_client.GetInfoRun.abnormal_n81i
" + fi + elif [ $mem_police_flag_t -eq 0 ]&&[ -z "${mem_baseInfo_police}" ];then + mem_detail_police="\"\",,," + mem_baseInfo_police="【${mem_detail_nopolice_arr[0]}】"${mem_police_arr[4]}${mem_detail_nopolice_arr[((${mem_police_arr[0]}-1))]}" i18n_client.GetInfoRun.normal_n81i
" + fi + done + memResult_baseInfo_police=${memResult_baseInfo_police}${mem_baseInfo_police} + else + mem_detail_police="\"\",,," + fi + memResult_detail=${memResult_detail}${mem_detail_police}${mem_detail_nopolice} + + + #memResult_detail="${memResult_detail}""\"\",,,"${swap_total}","${swap_free}","${mem_total}","${mem_used}","${mem_free}","${mem_shiyonglv}","$'\n' + + # disk info + disk_total_size=`awk '{total+=$2}END{print total}' ${diskInfo}` # Kb + disk_total_used_size=`awk '{total+=$3}END{print total}' ${diskInfo}` + disk_total_shiyonglv=`echo "scale=2;(${disk_total_used_size}*100)/${disk_total_size}"|bc|awk '{printf "%.2f",$0}'` + diskResult_baseInfo=${diskResult_baseInfo}${sep}"disk-"${index}"i18n_client.SystemInfo.diskSize_n81i:"`echo "scale=2;${disk_total_size}/1024/1024"|bc|awk '{printf "%.2f",$0}'`"G,i18n_client.SystemInfo.used2_n81i "${disk_total_shiyonglv}"% ;" + getDiskBase ${diskInfo} + getDiskDetail + + # net info + #net_avai_if_arr=($(awk 'NR==1{print $0}' ${netInfo})) + #net_all_if_arr=($(awk 'NR>1{print}' ${netInfo} | awk -F ':' '{print $1 NR}')) + #getNetInfo +} + +function getCpuBase2 { + arr1=($(awk '/^[0-2]/{print $9}' $1|awk 'NR>2{print $0}')) + arr2=($(awk '{print $4}' $2)) + + for((i=0;i<${#arr1[@]};i++));do + cpu_t2=`bc <<<100-${arr1[$i]} |awk '{printf "%.2f",$0}'` + cpuResult_baseInfo=${cpuResult_baseInfo}${sep}"cpu"${index}"-$i i18n_client.SystemInfo.mhz_n81i"${arr2[$i]}"MHz,i18n_client.SystemInfo.shiyonglv_n81i "${cpu_t2}"%; " + done +} + +function getCpuDetail { + cpu_t3=`awk '/^[0-2]/{print $0}' $1|awk 'NR>1{print $0}'` + + for((i=2;i<=`echo "${cpu_t3}"|awk 'END{print NR}'`;i++));do + cpu_row=`echo "${cpu_t3}"|awk 'NR=="'$i'"{print $0}'` + cpu_idle=`echo "${cpu_row}"|awk '{print $9}'` + cpu_shiyonglv_t=`bc <<<100-${cpu_idle} |awk '{printf "%.2f",$0}'` + + cpu_detail_nopolice="cpu${index}-$((i-2)),"`echo "${cpu_row}"|awk '{print $4}'`","`echo "${cpu_row}"|awk '{print $6}'`","`echo "${cpu_row}"|awk '{print $7}'`","`echo "${cpu_row}"|awk '{print $5}'`","`echo "${cpu_row}"|awk '{print $9}'`","${cpu_shiyonglv_t}","`awk 'NR=="'$((i-1))'"{print $4}' $2`$'\n' + + # police + if [ ! -z $cpu_polices ] + then + OLD_IFS="$IFS" + IFS="," + cpu_detail_nopolice_arr=(${cpu_detail_nopolice}) + IFS=$OLD_IFS + cpu_police_most_level=0 + cpu_police_flag_t=0 #临时变量 + cpu_baseInfo_police="" + for((j=0;j<${#cpu_polices_arr[@]};j++));do + cpu_detail_police_t="" + OLD_IFS="$IFS" + IFS="|" + cpu_police_arr=(${cpu_polices_arr[$j]}) + IFS=$OLD_IFS + + if (($(echo "${cpu_detail_nopolice_arr[((${cpu_police_arr[0]}-1))]} ${cpu_police_arr[1]} ${cpu_police_arr[2]}"|bc) == 1)) + then #触发告警 + cpu_detail_police_t=${cpu_police_arr[0]}","${cpu_police_arr[3]}","${cpu_police_arr[2]}"," + cpu_police_flag=1 + cpu_police_flag_t=1 + if ((${cpu_police_arr[3]} > ${cpu_police_most_level})) + then + cpu_police_most_level=${cpu_police_arr[3]} + cpu_detail_police=$cpu_detail_police_t + cpu_baseInfo_police="【cpu${index}-$((i-2))】"${cpu_police_arr[4]}${cpu_detail_nopolice_arr[((${cpu_police_arr[0]}-1))]}"% i18n_client.GetInfoRun.abnormal_n81i
" + fi + elif [ $cpu_police_flag_t -eq 0 ]&&[ -z "${cpu_baseInfo_police}" ];then + cpu_detail_police="\"\",,," + cpu_baseInfo_police="【cpu${index}-$((i-2))】"${cpu_police_arr[4]}${cpu_detail_nopolice_arr[((${cpu_police_arr[0]}-1))]}"% i18n_client.GetInfoRun.normal_n81i
" + fi + done + cpuResult_baseInfo_police=${cpuResult_baseInfo_police}${cpu_baseInfo_police} + else + cpu_detail_police="\"\",,," + fi + cpuResult_detail=${cpuResult_detail}${cpu_detail_police}${cpu_detail_nopolice} + done + cpuResult_detail=${cpuResult_detail}"\"\",,,cpu${index},"`awk 'NR==4{print $4}' $1`","`awk 'NR==4{print $6}' $1`","`awk 'NR==4{print $7}' $1`","`awk 'NR==4{print $5}' $1`","`awk 'NR==4{print $9}' $1`","${cpu_shiyonglv}","${cpu_averMHz}$'\n' +} + +function getDiskBase { + disk_size_arr=($(awk '{print $2}' $1)) + disk_used_arr=($(awk '{print $3}' $1)) + disk_avai_arr=($(awk '{print $4}' $1)) # available + disk_usep_arr=($(awk '{print $5}' $1)) + disk_moun_arr=($(awk '{print $6}' $1)) # mount on + + for((i=0;i<${#disk_size_arr[@]};i++));do + disk_size=`echo "scale=2;${disk_size_arr[$i]}/1024/1024"|bc|awk '{printf "%.2f",$0}'` # Gb + disk_used=`echo "scale=2;${disk_used_arr[$i]}/1024/1024"|bc|awk '{printf "%.2f",$0}'` + disk_avai=`echo "scale=2;${disk_avai_arr[$i]}/1024/1024"|bc|awk '{printf "%.2f",$0}'` + disk_usep=${disk_usep_arr[$i]} + disk_moun=${disk_moun_arr[$i]} + + diskResult_baseInfo=${diskResult_baseInfo}${sep}"【disk-$index:"${disk_moun}"】i18n_client.SystemInfo.size_n81i "${disk_size}"G, i18n_client.SystemInfo.used1_n81i "${disk_used}"G, i18n_client.SystemInfo.spaceRemain_n81i "${disk_avai}"G, i18n_client.SystemInfo.shiyonglv_n81i "${disk_usep}" ; " + done +} + +function getDiskDetail { + disk_total_num=`echo "${disk_total_num}+${#disk_size_arr[@]}"|bc` + for((i=0;i<${#disk_size_arr[@]};i++));do + disk_size=`echo "scale=2;${disk_size_arr[$i]}/1024/1024"|bc|awk '{printf "%.2f",$0}'` # Gb + disk_avai=`echo "scale=2;${disk_avai_arr[$i]}/1024/1024"|bc|awk '{printf "%.2f",$0}'` + disk_detail_nopolice="disk-$index:"${disk_moun_arr[$i]}","${disk_size}","${disk_avai}","${disk_usep_arr[$i]%\%*}",0,"$'\n' + OLD_IFS=$IFS + IFS="," + disk_detail_nopolice_arr=(${disk_detail_nopolice}) + IFS=$OLD_IFS + + # police + if [ ! -z $disk_polices ] + then + disk_police_most_level=0 + disk_police_flag_t=0 #临时变量 + disk_baseInfo_police="" + for((j=0;j<${#disk_polices_arr[@]};j++));do + disk_detail_police_t="" + OLD_IFS="$IFS" + IFS="|" + disk_police_arr=(${disk_polices_arr[$j]}) + IFS=$OLD_IFS + + if (($(echo "${disk_detail_nopolice_arr[((${disk_police_arr[0]}-1))]} ${disk_police_arr[1]} ${disk_police_arr[2]}"|bc) == 1)) + then #触发告警 + disk_detail_police_t=${disk_police_arr[0]}","${disk_police_arr[3]}","${disk_police_arr[2]}"," + disk_police_flag=1 + disk_police_flag_t=1 + if ((${disk_police_arr[3]} > ${disk_police_most_level})) + then + disk_police_most_level=${disk_police_arr[3]} + disk_detail_police=$disk_detail_police_t + disk_baseInfo_police="【${disk_detail_nopolice_arr[0]}】"${disk_police_arr[4]}${disk_detail_nopolice_arr[((${disk_police_arr[0]}-1))]}"% i18n_client.GetInfoRun.abnormal_n81i
" + fi + elif [ $disk_police_flag_t -eq 0 ]&&[ -z "${disk_baseInfo_police}" ];then + disk_detail_police="\"\",,," + disk_baseInfo_police="【${disk_detail_nopolice_arr[0]}】"${disk_police_arr[4]}${disk_detail_nopolice_arr[((${disk_police_arr[0]}-1))]}" i18n_client.GetInfoRun.normal_n81i
" + fi + done + diskResult_baseInfo_police=${diskResult_baseInfo_police}${disk_baseInfo_police} + else + disk_detail_police="\"\",,," + fi + diskResult_detail=${diskResult_detail}${disk_detail_police}${disk_detail_nopolice} + done +} + +function getNetInfo { + # 处理特殊网卡信息的内容 + special_base_row=`awk 'NR==1{print $0}' ${netInfo}3` # 第一行 + special_base_11=`echo ${special_base_row} | awk -F '"' '{print $2}'` # 11列 + special_base_11=${sep}${special_base_11#*$sep} + special_base_12=`echo $special_base_row | awk -F '"' '{print $4}'` # 12列 + special_base_12=${sep}${special_base_12#*$sep} + special_base_t=${special_base_11}${special_base_12} + special_base_t=${special_base_t//$sep/\!} + OLDIFS=$IFS + IFS="\!" + special_base_t_arr=(${special_base_t}) + IFS=$OLD_IFS + + special_base="" + for((i=1;i<${#special_base_t_arr[@]};i++));do + special_base=${special_base}"${sep}if${index}-"${special_base_t_arr[$i]} + done + special_detail_rows=`awk 'NR>2{print}' ${netInfo}3` # details行下方所有行 + special_detail_rows_arr=($special_detail_rows) # details下方所有行的数组,每个元素为一行内容 + + #special_if_t=`echo ${special_detail_rows}|awk -F ',' '{print $4}'` # 取每行第三、四个逗号之间的网卡名 + special_if_arr=() # 网卡名称数组 + + special_if_baseInfo="" # 初始化特殊网卡基础信息 + for ((i=0;i<${#special_detail_rows_arr[@]};i++));do + special_detail_row=`echo ${special_detail_rows_arr[$i]} | awk -F ',' '{print gensub($4,"if"'$index'"-"$4,1)}'` # detail行网卡名替换为ifx-开头的名字 + netResult_detail=${netResult_detail}${special_detail_row}$'\n' + + special_if_baseInfo=${special_if_baseInfo}${special_base_12}${special_base_11} + special_if_arr[$i]=`echo ${special_detail_rows_arr[$i]}| awk -F ',' '{print $4}'` + done + sys_net_total_num=`echo "${sys_net_total_num}+${#net_all_if_arr[@]}"|bc` + net_total_num=`echo "${net_total_num}+${#net_avai_if_arr[@]}"|bc` + net_avai_baseInfo="" + net_disa_baseInfo="" + + for((i=0;i<${#net_all_if_arr[@]};i++));do + ifName_t=${net_all_if_arr[$i]} + ifName=${ifName_t%?} + echo ${special_if_arr[0]}"--"${special_if_arr[1]}"--"${special_if_arr[2]}"--"${ifName} + if echo "${special_if_arr[@]}"|grep -w "${ifName}" &>/dev/null;then + let "net_total_num--" + let "sys_net_total_num--" + continue + fi + + net_rowNum=$((${net_all_if_arr[$i]: -1}+1)) + net_if_name_t=`awk 'NR=="'${net_rowNum}'"{print $1}' ${netInfo}` + net_if_name=${net_if_name_t%?} + is_avai=`echo "${net_avai_if_arr[@]}" | grep -wq "${net_all_if_arr[$i]%?}" && echo "1" || echo "0"` + if [ "1" -eq "$is_avai" ] + then + echo "#!/bin/bash"$'\n'"ethtool ${net_if_name}" > ethtool.sh + net_if_ethtoolResult=`ssh -C $value "/bin/bash" < ethtool.sh` + net_if_speed_t=`echo "${net_if_ethtoolResult}"|grep "Speed:"|awk '{print $2}'` + if [ ${#net_if_speed_t} -lt 1 ] + then + net_if_speed=0 + else + net_if_speed=${net_if_speed_t:0:${#net_if_speed_t}-4} + fi + net_if_rxByte1=`awk 'NR=="'${net_rowNum}'"{print $2}' ${netInfo}` + net_if_rxByte2=`awk 'NR=="'${net_rowNum}'"{print $2}' ${netInfo}2` + net_if_rxBps=`echo "scale=2;($net_if_rxByte2-$net_if_rxByte1)*8/5"|bc|awk '{printf "%.2f",$0}'` + net_if_rxPackets1=`awk 'NR=="'${net_rowNum}'"{print $3}' ${netInfo}` + net_if_rxPackets2=`awk 'NR=="'${net_rowNum}'"{print $3}' ${netInfo}2` + net_if_rxPps_t=`echo "($net_if_rxPackets2-$net_if_rxPackets1)"|bc` + net_if_rxPps=`echo "scale=2;($net_if_rxPackets2-$net_if_rxPackets1)*8/5"|bc|awk '{printf "%.2f",$0}'` + net_if_txByte1=`awk 'NR=="'${net_rowNum}'"{print $10}' ${netInfo}` + net_if_txByte2=`awk 'NR=="'${net_rowNum}'"{print $10}' ${netInfo}` + net_if_txBps=`echo "scale=2;($net_if_txByte2-$net_if_txByte1)*8/5"|bc|awk '{printf "%.2f",$0}'` + net_if_txPackets1=`awk 'NR=="'${net_rowNum}'"{print $11}' ${netInfo}` + net_if_txPackets2=`awk 'NR=="'${net_rowNum}'"{print $11}' ${netInfo}2` + net_if_txPps_t=`echo "($net_if_rxPackets2-$net_if_rxPackets1)"|bc` + net_if_txPps=`echo "scale=2;($net_if_rxPackets2-$net_if_rxPackets1)*8/5"|bc|awk '{printf "%.2f",$0}'` + net_if_rxError1=`awk 'NR=="'${net_rowNum}'"{print $4}' ${netInfo}` + net_if_rxError2=`awk 'NR=="'${net_rowNum}'"{print $4}' ${netInfo}2` + net_if_txError1=`awk 'NR=="'${net_rowNum}'"{print $12}' ${netInfo}` + net_if_txError2=`awk 'NR=="'${net_rowNum}'"{print $12}' ${netInfo}2` + net_if_rxDrop1=`awk 'NR=="'${net_rowNum}'"{print $5}' ${netInfo}` + net_if_rxDrop2=`awk 'NR=="'${net_rowNum}'"{print $5}' ${netInfo}2` + net_if_txDrop1=`awk 'NR=="'${net_rowNum}'"{print $13}' ${netInfo}` + net_if_txDrop2=`awk 'NR=="'${net_rowNum}'"{print $13}' ${netInfo}2` + + if [ $net_if_rxPps_t -gt 0 ] + then + net_if_rxErrorPerc=`echo "scale=2;($net_if_rxError2-$net_if_rxError1)*100/($net_if_rxPackets2-$net_if_rxPackets1)"|bc|awk '{printf "%.2f",$0}'` + net_if_rxDropPerc=`echo "scale=2;($net_if_rxDrop2-$net_if_rxDrop1)*100/($net_if_rxPackets2-$net_if_rxPackets1)"|bc|awk '{printf "%.2f",$0}'` + else + net_if_rxErrorPerc=0.00 + net_if_rxDropPerc=0.00 + fi + if [ $net_if_txPps_t -gt 0 ] + then + net_if_txErrorPerc=`echo "scale=2;($net_if_txError2-$net_if_txError1)*100/($net_if_txPackets2-$net_if_txPackets1)"|bc|awk '{printf "%.2f",$0}'` + net_if_txDropPerc=`echo "scale=2;($net_if_txDrop2-$net_if_txDrop1)*100/($net_if_txPackets2-$net_if_txPackets1)"|bc|awk '{printf "%.2f",$0}'` + else + net_if_txErrorPerc=0.00 + net_if_txDropPerc=0.00 + fi + net_avai_baseInfo=${net_avai_baseInfo}${sep}"if"${index}"-"${net_if_name}" i18n_client.SystemInfo.netSpeed_n81i"${net_if_speed}"Mbps, i18n_client.SystemInfo.input_n81i"${net_if_rxBps}"bps、"${net_if_rxPps}"pps, Output"${net_if_txBps}"bps、"${net_if_txPps}"pps; " + net_detail_nopolice="if${index}-"${net_if_name}","${net_if_rxPackets2}","${net_if_txPackets2}","${net_if_rxByte2}","${net_if_txByte2}","${net_if_rxError2}","${net_if_txError2}","${net_if_rxDrop2}","${net_if_txDrop2}","${net_if_speed}","${net_if_rxBps}","${net_if_txBps}","${net_if_rxPps}","${net_if_txPps}","${net_if_rxErrorPerc}","${net_if_txErrorPerc}","${net_if_rxDropPerc}","${net_if_txDropPerc}$'\n' + #netResult_detail=${netResult_detail}"\"\",,,if${index}-"${net_if_name}","${net_if_rxPackets2}","${net_if_txPackets2}","${net_if_rxByte2}","${net_if_txByte2}","${net_if_rxError2}","${net_if_txError2}","${net_if_rxDrop2}","${net_if_txDrop2}","${net_if_speed}","${net_if_rxBps}","${net_if_txBps}","${net_if_rxPps}","${net_if_txPps}","${net_if_rxErrorPerc}","${net_if_txErrorPerc}","${net_if_rxDropPerc}","${net_if_txDropPerc}$'\n' + # police + if [ ! -z $net_polices ] + then + OLD_IFS="$IFS" + IFS="," + net_detail_nopolice_arr=(${net_detail_nopolice}) + IFS=$OLD_IFS + net_police_most_level=0 + net_police_flag_t=0 #临时变量 + net_baseInfo_police="" + for((j=0;j<${#net_polices_arr[@]};j++));do + net_detail_police_t="" + OLD_IFS="$IFS" + IFS="|" + net_police_arr=(${net_polices_arr[$j]}) + IFS=$OLD_IFS + + if (($(echo "${net_detail_nopolice_arr[((${net_police_arr[0]}-1))]} ${net_police_arr[1]} ${net_police_arr[2]}"|bc) == 1)) + then #触发告警 + net_detail_police_t=${net_police_arr[0]}","${net_police_arr[3]}","${net_police_arr[2]}"," + net_police_flag=1 + net_police_flag_t=1 + if ((${net_police_arr[3]} > ${net_police_most_level})) + then + net_police_most_level=${net_police_arr[3]} + net_detail_police=$net_detail_police_t + net_baseInfo_police="【${net_detail_nopolice_arr[0]}】"${net_police_arr[4]}${net_detail_nopolice_arr[((${net_police_arr[0]}-1))]}"% i18n_client.GetInfoRun.abnormal_n81i
" + fi + elif [ $net_police_flag_t -eq 0 ]&&[ -z "${net_baseInfo_police}" ];then + net_detail_police="\"\",,," + net_baseInfo_police="【${net_detail_nopolice_arr[0]}】"${net_police_arr[4]}${net_detail_nopolice_arr[((${net_police_arr[0]}-1))]}"% i18n_client.GetInfoRun.normal_n81i
" + fi + done + netResult_baseInfo_police=${netResult_baseInfo_police}${net_baseInfo_police} + else + net_detail_police="\"\",,," + fi + netResult_detail=${netResult_detail}${net_detail_police}${net_detail_nopolice} + else + net_disa_baseInfo=${net_disa_baseInfo}${sep}"if"${index}"-"${net_if_name}"i18n_client.SystemInfo.disable_n81i; " + fi + done + + sys_net_total_num=`echo "${sys_net_total_num}+${#special_detail_rows_arr[@]}"|bc` + net_total_num=`echo "$net_total_num+${#special_detail_rows_arr[@]}"|bc` + netResult_baseInfo=${netResult_baseInfo}"${sep}if"${index}"-"${#special_detail_rows_arr[@]}"i18n_client.SystemInfo.insert_n81i: "${special_base}${net_avai_baseInfo}${net_disa_baseInfo}$'\n' +} + +# main +index=1 +flag=1 +while [ $flag -eq 1 ]; do + key='ip'${index} + value=`eval echo '$'${key}` + + if [ -z ${value} ] + then + flag=0 + else + getDetail ${key} ${value} + let "index++" + fi +done + +## result +# cpu +cpuResult_baseInfo=${cpuResult_baseInfo}"\"" +if ((${cpu_police_flag} == 0 )) + then + cpuResult_baseInfo_police="\""${cpuResult_baseInfo} + cpu_police_flag=1 + else + cpuResult_baseInfo_police="\""${cpuResult_baseInfo_police}"\"" + cpu_police_flag=0 +fi +echo "${cpuResult_taskInfo}""${cpu_police_flag},""\"${cpuResult_coreNum}""i18n_client.SystemInfo.core_n81i: ""${cpuResult_baseInfo}"",""${cpuResult_baseInfo_police}"$'\n'"details,""$((cpuResult_coreNum+index-1))"$'\n'"${cpuResult_detail}" > ${cpu_dataFileDir}/${date}".csv" #${cpuResult} + +# mem +memResult_baseInfo=${memResult_baseInfo}"\"" +if ((${mem_police_flag} == 0 )) + then + memResult_baseInfo_police=${memResult_baseInfo} + mem_police_flag=1 + else + memResult_baseInfo_police="\""${memResult_baseInfo_police}"\"" + mem_police_flag=0 +fi +echo "${memResult_taskInfo}"${mem_police_flag}",${memResult_baseInfo}"",""${memResult_baseInfo_police}"$'\n'"details,""$((index-1))"$'\n'"${memResult_detail}" > ${mem_dataFileDir}/${date}".csv" #${memResult} + +# disk +diskResult_baseInfo=${diskResult_baseInfo}"\"" +if ((${disk_police_flag} == 0 )) + then + diskResult_baseInfo_police=${diskResult_baseInfo} + disk_police_flag=1 + else + diskResult_baseInfo_police="\""${diskResult_baseInfo_police}"\"" + disk_police_flag=0 +fi +echo "${diskResult_taskInfo}"${disk_police_flag}",${diskResult_baseInfo}"",""${diskResult_baseInfo_police}"$'\n'"details,$disk_total_num"$'\n'"${diskResult_detail}" > ${disk_dataFileDir}/${date}".csv" #${diskResult} + +# net +netResult_baseInfo=${netResult_baseInfo}"\"" +if ((${net_police_flag} == 0 )) + then + netResult_baseInfo_police=${netResult_baseInfo} + net_police_flag=1 + else + netResult_baseInfo_police="\""${netResult_baseInfo_police}"\"" + net_police_flag=0 +fi +echo "${netResult_taskInfo}"${net_police_flag}",${netResult_baseInfo}"",""${netResult_baseInfo_police}"$'\n'"details,$net_total_num"$'\n'"${netResult_detail}" > ${net_dataFileDir}/${date}".csv" #${netResult} + +# sys +sysinfo=`cat ${sysinfoPath}` +echo "${sysResult_taskInfo}""${sysinfo}" > ${sys_dataFileDir}/${date}".csv" #${sysResult} diff --git a/linuxinstall/detectShell/monitor_net.py b/linuxinstall/detectShell/monitor_net.py new file mode 100644 index 0000000..9e0b8bc --- /dev/null +++ b/linuxinstall/detectShell/monitor_net.py @@ -0,0 +1,362 @@ +#!/usr/bin/env python +# -*- coding: UTF-8 -*- + +# created by zhongyoub +''' +get all net card info and write to file with csv format +time: ms +''' + +import time,re,os,csv +import ConfigParser +import StringIO +from datetime import datetime + +global cfg_path_str +global nic_path_str +global marsio_cmd +cfg_path_str="/home/nms/nc_config/net_net/net_net.cfg" +nic_path_str="/proc/net/dev" +marsio_cmd="monit_device" + +def round2(a): + return ("%.2f"%a) + +class monitor_net(): + def __init__(self): + self.seqId="" # seqId + self.id="" # 监测设置ID + self.cattory="" # 监测类别 + self.process="" # 进程名称 + + self.start_time=int(round(time.time()*1000)) # 监测服务启动时间 + self.delay=0 # 检测时延 + self.checktime=int(round(time.time()*1000)) # 本次检测时间 + self.try_times=1 # 尝试次数 + self.next_time=0 # 下次监测时间 self.start_time + self.interval + self.checkState=1 # 检测状态 + + self.checkGap=0 + self.config_path=cfg_path_str + self.nic_path=nic_path_str + + ''' + nic info + ''' + self.nic_info={"eth_name":"", "rx_packets":0, "tx_packets":0, "rx_bytes":0, "tx_bytes":0, + "rx_errs":0, "tx_errs":0, "rx_drop":0, "tx_drops":0, "speed":10000, + "rx_bps":0, "tx_bps":0, "rx_pps":0, "tx_pps":0, + "rx_err_perc":0, "tx_err_perc":0, "rx_drop_perc":0, "tx_drop_perc":0 } + self.marsio_info={"eth_name":"", "rx_packets":0, "tx_packets":0, "rx_bytes":0, "tx_bytes":0, + "rx_errs":0, "tx_errs":0, "rx_drop":0, "tx_drops":0, "speed":10000, + "rx_bps":0, "tx_bps":0, "rx_pps":0, "tx_pps":0, + "rx_err_perc":0, "tx_err_perc":0, "rx_drop_perc":0, "tx_drop_perc":0 } + # self.vf_dict={'0':'','1':'','2':''} + self.vf_list=[] + self.marsio_list=[] + + + ''' + read config file + ''' + def read_config(self): + ''' + with open(self.config_path, 'r') as f: + section_string = '[dummy_section]\n' + f.read() + ''' + + config=StringIO.StringIO() + config.write('[dummy_section]\n') + config.write(open(self.config_path).read()) + config.seek(0,os.SEEK_SET) + + cfg = ConfigParser.ConfigParser() + # cfg.readfp(section_string) + cfg.readfp(config) + pubInfo=cfg.get("dummy_section", "pubInfo") + self.seqId=pubInfo.split(",",3)[0] + self.id=pubInfo.split(",",3)[1] + self.cattory=pubInfo.split(",",3)[2] + self.process=pubInfo.split(",",3)[3] + + self.delay=cfg.get("dummy_section","checkOutTime") + self.try_times=cfg.get("dummy_section","checkMaxTimes") + self.checkGap=int(cfg.get("dummy_section","checkGap"))*60*1000 # ms + self.next_time=self.start_time+self.checkGap + self.checkState=cfg.get("dummy_section","checkState") + + + ''' + get net card info/home/nms/nc_config/net_net + ''' + def get_vfnet_info(self): + net_info=open("/proc/net/dev","r") + info=net_info.readlines() + net_info.close() +# print self.marsio_list + for line in info: # find nic name like ens*f* + self.nic_info={"eth_name":"", "rx_packets":0, "tx_packets":0, "rx_bytes":0, "tx_bytes":0, + "rx_errs":0, "tx_errs":0, "rx_drop":0, "tx_drops":0, "speed":10000, + "rx_bps":0, "tx_bps":0, "rx_pps":0, "tx_pps":0, + "rx_err_perc":0, "tx_err_perc":0, "rx_drop_perc":0, "tx_drop_perc":0 } + if re.search(r'ens.f.',line): + field=line.split() + self.nic_info["eth_name"]=field[0].split(":")[0] + self.nic_info["rx_bytes"]=field[1] + self.nic_info["rx_packets"]=field[2] + self.nic_info["rx_errs"]=field[3] + self.nic_info["rx_drop"]=field[4] + self.nic_info["tx_bytes"]=field[9] + self.nic_info["tx_packets"]=field[10] + self.nic_info["tx_errs"]=field[11] + self.nic_info["tx_drop"]=field[12] + # self.vf_dict[str(i)]=self.nic_info + # print "nic_info" + # print self.nic_info + self.vf_list.append(self.nic_info) + # print self.vf_list +# print self.vf_list[str(i)] + + ''' + eth_name=field[0].split(":")[0] + rx_bytes=field[1] + rx_packets=field[2] + rx_errs=field[3] + rx_drop=field[4] + tx_bytes=field[9] + tx_packts=field[10] + tx_errs=field[11] + tx_drop=field[12] + return(eth_name, int(rx_bytes),int(rx_packets),int(rx_errs),int(rx_drop),int(tx_bytes), + int(tx_packts),int(tx_errs),int(tx_drop)) + ''' + + ''' + get marsio net card info by open(monit_device) + ''' + def get_marsionet_info(self): + info=os.popen(marsio_cmd) + for line in info: + if re.search(r'ens.f*',line): + self.marsio_info["eth_name"]=line.split(",")[1].split(":")[1].strip() + if re.search(r'Accu',line): + self.marsio_info["rx_packets"]=line.split()[1] + self.marsio_info["rx_bytes"]=int(line.split()[2])/8 # bit to byte(float) + self.marsio_info["rx_drop"]=line.split()[9] + self.marsio_info["rx_errs"]=line.split()[4] + self.marsio_info["tx_packets"]=line.split()[6] + self.marsio_info["tx_bytes"]=int(line.split()[7])/8 + self.marsio_info["tx_errs"]=line.split()[8] + self.marsio_info['tx_drop']=line.split()[10] + + if re.search(r'Second',line): + self.marsio_info["rx_bps"]=line.split()[3] + rx_packets=self.marsio_info["rx_pps"]=line.split()[2] + tx_packets=self.marsio_info["tx_pps"]=line.split()[7] + self.marsio_info["tx_bps"]=line.split()[8] + + rx_err_per=line.split()[5] + tx_err_per=line.split()[9] + if int(rx_packets)!=0: + self.marsio_info["rx_err_perc"]=round2(float(rx_err_per)/int(rx_packets)) + else: + self.marsio_info["rx_err_perc"]=round2(0) +# print self.marsio_info["rx_err_perc"] + if int(tx_packets)!=0: + self.marsio_info["tx_err_perc"]=round2(float(tx_err_per)/int(tx_packets)) + else: + self.marsio_info["tx_err_perc"]=round2(0) + # print self.marsio_info["tx_err_perc"] + rx_drop_per=line.split()[10] + tx_drop_per=line.split()[11] + if int(rx_packets)!=0: + self.marsio_info["rx_drop_perc"]=round2(float(rx_drop_per)/int(rx_packets)) + else: + self.marsio_info["rx_drop_perc"]=round2(0) +# print self.marsio_info["rx_drop_perc"] + if int(tx_packets)!=0: + self.marsio_info["tx_drop_perc"]=round2(float(tx_drop_per)/int(tx_packets)) + else: + self.marsio_info["tx_drop_perc"]=round2(0) +# print self.marsio_info["tx_drop_perc"] + self.marsio_list.append(self.marsio_info) +# print "marsio_info" +# print self.marsio_info + +def list_append(list1, dict1): + list1.append(dict1["eth_name"]) + list1.append(dict1["rx_packets"]) + list1.append(dict1["tx_packets"]) + list1.append(dict1["rx_bytes"]) + list1.append(dict1["tx_bytes"]) + list1.append(dict1["rx_errs"]) + list1.append(dict1["tx_errs"]) + list1.append(dict1["rx_drop"]) + list1.append(dict1["tx_drop"]) + list1.append(dict1["speed"]) + list1.append(dict1["rx_bps"]) + list1.append(dict1["tx_bps"]) + list1.append(dict1["rx_pps"]) + list1.append(dict1["tx_pps"]) + list1.append(dict1["rx_err_perc"]) + list1.append(dict1["tx_err_perc"]) + list1.append(dict1["rx_drop_perc"]) + list1.append(dict1["tx_drop_perc"]) + +def main(): + monitor=monitor_net() + monitor.read_config() + monitor.chectime=int(round(time.time()*1000)) + monitor.get_marsionet_info() + list3=monitor.marsio_list + monitor.get_vfnet_info() + list1=monitor.vf_list +# print "list1" +# print list1 + monitor.vf_list=[] +# print monitor.vf_list + # monitor.vf_list.clear() + time.sleep(1) + monitor.get_vfnet_info() + list2=monitor.vf_list +# print "list2" +# print list2 + for x, y in zip(list1,list2): + rx_bytes_pers=int(y["rx_bytes"])-int(x["rx_bytes"]) + tx_bytes_pers=int(y["tx_bytes"])-int(x["tx_bytes"]) + rx_packet_pers=float(y["rx_packets"])-int(x["rx_packets"]) + tx_packet_pers=float(y["tx_packets"])-int(x["tx_packets"]) + + rx_bps=rx_bytes_pers*8 + rx_pps=rx_packet_pers + tx_bps=tx_bytes_pers*8 + tx_pps=tx_packet_pers + if rx_packet_pers >0: + rx_err_rate=(int(y["rx_errs"])-int(x["rx_errs"]))/rx_packet_pers + else: + rx_err_rate=0 + if tx_packet_pers>0: + tx_err_rate=(int(y["tx_errs"])-int(x["tx_errs"]))/tx_packet_pers + else: + tx_err_rate=0 + if rx_packet_pers>0: + rx_drop_rate=(int(y["rx_drop"])-int(x["rx_drop"]))/rx_packet_pers + else: + rx_drop_rate=0 + if tx_packet_pers>0: + tx_drop_rate=(int(y["tx_drop"])-int(x["tx_drop"]))/tx_packet_pers + else: + tx_drop_rate=0 + ''' + y["rx_bps"]=round2(rx_bps) + y["rx_pps"]=round2(rx_pps) + y["tx_bps"]=round2(tx_bps) + y["tx_pps"]=round2(tx_pps) + ''' + y["rx_err_perc"]=round2(rx_err_rate) + y["tx_err_perc"]=round2(tx_err_rate) + y["rx_drop_perc"]=round2(rx_drop_rate) + y["tx_drop_perc"]=round2(tx_drop_rate) + +# print list2 +# print list3 + vf_num=len(monitor.vf_list) + # print monitor.vf_list + # print vf_num + marsio_num=len(list3) + + csv_file=datetime.now().strftime("%Y%m%d%H%M%S") + + header=[monitor.seqId,monitor.id,monitor.cattory,monitor.process,monitor.start_time,monitor.delay, + monitor.chectime,monitor.try_times,monitor.next_time,monitor.checkState] + + first_str=str(vf_num)+"i18n_client.SystemInfo.insert_n81i: " + for each in list2: + first_str=first_str+"$@$"+each["eth_name"]+ \ + " i18n_client.SystemInfo.netSpeed_n81i10000Mbps,"+"i18n_client.SystemInfo.input_n81i"+ \ + str(each["rx_bps"])+"bps、"+str(each["rx_pps"])+"pps,"+"Output"+str(each["tx_bps"])+"bps、"+str(each["tx_pps"])+ \ + "pps;" + + second_str=str(marsio_num)+"i18n_client.SystemInfo.insert_n81i: " + for each in list3: + second_str=second_str+"$@$"+each["eth_name"]+ \ + " i18n_client.SystemInfo.netSpeed_n81i10000Mbps,"+"i18n_client.SystemInfo.input_n81i"+ \ + str(each["rx_bps"])+"bps、 "+str(each["rx_pps"])+"pps,"+"Output"+str(each["tx_bps"])+"bps、"+str(each["tx_pps"])+ \ + "pps;" + + four_1=['\"','',''] + four_2=['\"','',''] + four_3=['\"','',''] + if len(list2)>1: + first_dict=list2[0] + second_dict=list2[1] + list_append(four_1,first_dict) + list_append(four_2,second_dict) + elif len(list2)==1: + first_dict=list2[0] + list_append(four_1,first_dict) + four_2=[] + else: + four_1=[] + four_2=[] + if len(list3)>0: + three_dict=list3[0] + ''' + three_dict["rx_bps"]=round2(int(three_dict["rx_bps"])) + three_dict["rx_pps"]=round2(int(three_dict["rx_pps"])) + three_dict["tx_bps"]=round2(int(three_dict["tx_bps"])) + three_dict["tx_bps"]=round2(int(three_dict["tx_bps"])) + three_dict["rx_err_perc"]=round2(int(three_dict["rx_err_perc"])) + three_dict["tx_err_perc"]=round2(int(three_dict["tx_err_perc"])) + three_dict["rx_drop_perc"]=round2(int(three_dict["rx_drop_perc"])) + three_dict["tx_drop_perc"]=round2(int(three_dict["tx_drop_perc"])) + ''' + list_append(four_3,three_dict) + else: + four_3=[] + ''' + four_1.append(first_list["eth_name"]) + four_1.append(first_list["rx_packets"]) + four_1.append(first_list["tx_packets"]) + four_1.append(first_list["rx_bytes"]) + four_1.append(first_list["tx_bytes"]) + four_1.append(first_list["rx_errs"]) + four_1.append(first_list["tx_errs"]) + four_1.append(first_list["rx_drop"]) + four_1.append(first_list["tx_drop"]) + four_1.append(first_list["speed"]) + four_1.append(first_list["rx_bps"]) + four_1.append(first_list["tx_bps"]) + four_1.append(first_list["rx_pps"]) + four_1.append(first_list["tx_pps"]) + four_1.append(first_list["rx_err_perc"]) + four_1.append(first_list["tx_err_perc"]) + four_1.append(first_list["rx_drop_perc"]) + ''' +# print four_1 +# print four_2 +# print four_3 + header.append(first_str) + header.append(second_str) + two_list=["details"] + two_list.append((vf_num+marsio_num)) + + with open(csv_file+".csv","w") as f: + f_writer=csv.writer(f,lineterminator='\n') + f_writer.writerow(header) + f_writer.writerow(two_list) + if len(four_1): + f_writer.writerow(four_1) + if len(four_2): + f_writer.writerow(four_2) + if len(four_3): + f_writer.writerow(four_3) + f.close() + +if __name__ == '__main__': + main() + exit(0) + + + + diff --git a/linuxinstall/detectShell/remote_net.sh b/linuxinstall/detectShell/remote_net.sh new file mode 100644 index 0000000..0476b01 --- /dev/null +++ b/linuxinstall/detectShell/remote_net.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +python /root/zhong/monitor_net.py #py脚本的路径,需要手动填写 +cat `ls|grep csv` +rm -f *.csv diff --git a/linuxinstall/detectShell/sysinfo b/linuxinstall/detectShell/sysinfo new file mode 100644 index 0000000..47eeb21 --- /dev/null +++ b/linuxinstall/detectShell/sysinfo @@ -0,0 +1,29 @@ +"$@$1-localhost.localdomain): 3.10.0-693.el7.x86_64, 8i18n_client.SystemInfo.message.core_n81i CPU, 1466.65MHz, 15.44i18n_client.SystemInfo.message.memery_n81i, 1885477224i18n_client.SystemInfo.message.disk_n81i, 4i18n_client.SystemInfo.message.netcard_n81i$@$2-localhost.localdomain): 3.10.0-693.el7.x86_64, 8i18n_client.SystemInfo.message.core_n81i CPU, 1498.72MHz, 15.44i18n_client.SystemInfo.message.memery_n81i, 1885477224i18n_client.SystemInfo.message.disk_n81i, 4i18n_client.SystemInfo.message.netcard_n81i$@$3-localhost.localdomain): 3.10.0-693.el7.x86_64, 8i18n_client.SystemInfo.message.core_n81i CPU, 1567.90MHz, 15.44i18n_client.SystemInfo.message.memery_n81i, 1885477224i18n_client.SystemInfo.message.disk_n81i, 4i18n_client.SystemInfo.message.netcard_n81i","$@$1-localhost.localdomain): 3.10.0-693.el7.x86_64, 8i18n_client.SystemInfo.message.core_n81i CPU, 1466.65MHz, 15.44i18n_client.SystemInfo.message.memery_n81i, 1885477224i18n_client.SystemInfo.message.disk_n81i, 4i18n_client.SystemInfo.message.netcard_n81i$@$2-localhost.localdomain): 3.10.0-693.el7.x86_64, 8i18n_client.SystemInfo.message.core_n81i CPU, 1498.72MHz, 15.44i18n_client.SystemInfo.message.memery_n81i, 1885477224i18n_client.SystemInfo.message.disk_n81i, 4i18n_client.SystemInfo.message.netcard_n81i$@$3-localhost.localdomain): 3.10.0-693.el7.x86_64, 8i18n_client.SystemInfo.message.core_n81i CPU, 1567.90MHz, 15.44i18n_client.SystemInfo.message.memery_n81i, 1885477224i18n_client.SystemInfo.message.disk_n81i, 4i18n_client.SystemInfo.message.netcard_n81i" +details,3 +"",,,1-localhost.localdomain),"3.10.0-693.el7.x86_64",8,1466.65,15.44,63.99,1885477224,4, +"",,,2-localhost.localdomain),"3.10.0-693.el7.x86_64",8,1498.72,15.44,63.99,1885477224,4, +"",,,3-localhost.localdomain),"3.10.0-693.el7.x86_64",8,1567.90,15.44,63.99,1885477224,4, +disk,9 +1:/,1884767064, +1:/boot,505580, +1:/boot/efi,204580, +2:/,1884767064, +2:/boot,505580, +2:/boot/efi,204580, +3:/,1884767064, +3:/boot,505580, +3:/boot/efi,204580, +net,12 +1-enp0s31f6,Available,100,10.0.6.247,255.255.255.0,10.0.6.100,30:9c:23:4d:9c:93, +1-wlp3s0,Unavailable,0,0.0.0.0,0.0.0.0,0,0,0,0,f8:28:19:d4:13:db, +1-virbr0-nic,Unavailable,10,0.0.0.0,0.0.0.0,0,0,0,0,52:54:00:37:52:32, +1-virbr0,Available,0,192.168.122.1,255.255.255.0,10.0.6.100,52:54:00:37:52:32, +2-enp0s31f6,Available,100,10.0.6.247,255.255.255.0,10.0.6.100,30:9c:23:4d:9c:93, +2-wlp3s0,Unavailable,0,0.0.0.0,0.0.0.0,0,0,0,0,f8:28:19:d4:13:db, +2-virbr0-nic,Unavailable,10,0.0.0.0,0.0.0.0,0,0,0,0,52:54:00:37:52:32, +2-virbr0,Available,0,192.168.122.1,255.255.255.0,10.0.6.100,52:54:00:37:52:32, +3-enp0s31f6,Available,100,10.0.6.247,255.255.255.0,10.0.6.100,30:9c:23:4d:9c:93, +3-wlp3s0,Unavailable,0,0.0.0.0,0.0.0.0,0,0,0,0,f8:28:19:d4:13:db, +3-virbr0-nic,Unavailable,10,0.0.0.0,0.0.0.0,0,0,0,0,52:54:00:37:52:32, +3-virbr0,Available,0,192.168.122.1,255.255.255.0,10.0.6.100,52:54:00:37:52:32, + diff --git a/linuxinstall/install.sh b/linuxinstall/install.sh new file mode 100644 index 0000000..8164514 --- /dev/null +++ b/linuxinstall/install.sh @@ -0,0 +1,215 @@ +#!/bin/bash + +# --- set default value +DEFAULT_DATA_DIR="/home/nms/nmsdata" +DEFAULT_INSTALL_DIR="/home/nms/nmsclient" + +# --- set install dir +PRG="$0" +PRGDIR=`dirname "$PRG"` +CUR_PRGDIR=`cd "$PRGDIR"; pwd` + +if [ $# = 0 ] + then + echo -n "enter intall dir [default: $DEFAULT_INSTALL_DIR]:" + read INSTALL_DIR + if [ -z "$INSTALL_DIR" ]; then + INSTALL_DIR="$DEFAULT_INSTALL_DIR" + fi +else + INSTALL_DIR="$1" +fi + +if [ ! -d $INSTALL_DIR ] + then + mkdir -p $INSTALL_DIR +fi + +INSTALL_DIR=`cd "$INSTALL_DIR"; pwd` + +# --- check jdk and jdk-version +install_jdk=0 +javaversion=`java -version 2>&1|grep "java version"` +if [ -n "$javaversion" ] + then + # javaversion=${javaversion:14:3} + javavmajor=`echo $javaversion | cut -c15` + javavminor=`echo $javaversion | cut -c17` +# OS_TYPE=$( lsb_release -d| cut -d: -f2| cut -f2 ) +# if [ "`echo $OS_TYPE | cut -c1-6`" = "Ubuntu" ] +# then +# if [ 2 -gt $javavmajor ]; then +# if [ 6 -gt $javavminor ]; then +# install_jdk=1 +# fi +# fi +# else + if [[ 2 -gt $javavmajor && 6 -gt $javavminor ]]; then + install_jdk=1 + fi +# fi + else + install_jdk=1 +fi + +# --- install jdk +cd "$INSTALL_DIR"/.. +NMS_JDK="$(pwd)/nmsjdk" +JDK_DIR="$(pwd)/jdk1.7.0_80" +JDK_BIN_FILE=$CUR_PRGDIR"/jre_install/jdk-7u80-linux-i586.tar.gz" +if [ "`uname -i`" = "x86_64" ];then + JDK_BIN_FILE=$CUR_PRGDIR"/jre_install/jdk-7u80-linux-x64.tar.gz" +fi +if [ $install_jdk = 1 ] + then + if [ ! -e "$NMS_JDK" ] + then + echo "JDK bin file: $JDK_BIN_FILE" + echo "now, install jdk: $JDK_DIR" + sleep 3 + if [ ! -e "$JDK_DIR" ];then + mkdir -p $JDK_DIR + fi + tar -xzf $JDK_BIN_FILE -C $JDK_DIR --strip-components=1 || installJdk=1 + if [ -n "$installJdk" ];then + echo "install jdk failure, exit program" + exit 1 + fi + ln -s $JDK_DIR $NMS_JDK + echo "install jdk done" + fi +elif [ -n "$JAVA_HOME" ];then + ln -s $JAVA_HOME $NMS_JDK +else + echo "JDK bin file: $JDK_BIN_FILE" + echo "now, install jdk: $JDK_DIR" + sleep 3 + if [ ! -e "$JDK_DIR" ];then + mkdir -p $JDK_DIR + fi + tar -xzf $JDK_BIN_FILE -C $JDK_DIR --strip-components=1 || installJdk=1 + if [ -n "$installJdk" ];then + echo "install jdk failure, exit program" + exit 1 + fi + ln -s $JDK_DIR $NMS_JDK + echo "install jdk done" +fi +cd "$CUR_PRGDIR" + +echo "===========================================" +echo "NMS_JDK: $NMS_JDK" +echo "INSTALL_DIR: $INSTALL_DIR" +echo "===========================================" + +# --- copy file to install_dir +if [ "$INSTALL_DIR" == "$CUR_PRGDIR" ] + then + echo "install directory is current program directory..." +else + echo "install program, it may take a few time..." + CP_DIR=( + bin + lib + conf + shell + ) + #cp + for CP_NAME in ${CP_DIR[@]} + do + cp -a $CUR_PRGDIR"/$CP_NAME" $INSTALL_DIR + done +fi + + +function modify_file(){ + if [ $# != 2 ] + then + echo "usage: modify_file [prop_name] [prop_value]" + exit 0 + fi + prop_name="$1" + prop_value="$2" + #echo "modify_file $prop_name $prop_value" + if [ -z "$(cat $PROP_FILE |grep $prop_name)" ] + then + echo "" >> $PROP_FILE + echo "$prop_name=$prop_value" >> $PROP_FILE + else + sed -i "s@^$prop_name.*@$prop_name=$prop_value@" $PROP_FILE + fi +} + +# --- modify property +#-------------file path +echo -n "please enter data path, notice: this path not within $INSTALL_DIR, [default $DEFAULT_DATA_DIR]: " +read path +if [ -z "$path" ] + then + path="$DEFAULT_DATA_DIR" +fi +#-------------include path +echo -n "delete include path [default $INSTALL_DIR,$path ]: " +read include_path +if [ -z "$include_path" ] + then + include_path="$INSTALL_DIR,$path" +else + include_path="$INSTALL_DIR,$path,$include_path" +fi +#-------------exclude path +echo -n "delete exclude path [default $INSTALL_DIR/bin,$INSTALL_DIR/lib,$INSTALL_DIR/shell,$INSTALL_DIR/conf ]: " +read exclude_path +if [ -z "$exclude_path" ] + then + exclude_path="$INSTALL_DIR/bin,$INSTALL_DIR/lib,$INSTALL_DIR/shell" +else + exclude_path="$$INSTALL_DIR/bin,$INSTALL_DIR/lib,$INSTALL_DIR/shell,$exclude_path" +fi +#-------------nmsserver ip +echo -n "enter DataController ip: " +read server_ip +while [ -z "$server_ip" ] + do + echo -n "DataController ip cannot null, please enter ip: " + read server_ip +done +#-------------log4j dir +echo -n "enter logs path [default $path/nc_logs]: " +read logs_path +if [ -z "$logs_path" ] + then + logs_path="$path/nc_logs" +fi + +#path=${path//\//\\/} + +PROP_FILE=$INSTALL_DIR"/conf/myconfig.properties" +#echo "PROP_FILE: $PROP_FILE" +modify_file "local.data.path" $path +modify_file "common.del.path.include" $include_path +modify_file "common.del.path.exclude" $exclude_path +modify_file "server_host" $server_ip + +# modify log4j +PROP_FILE=$INSTALL_DIR"/conf/log4j.properties" +encoding=${LANG#*.} +modify_file "log4j.appender.stdout.encoding" $encoding +modify_file "log4j.appender.debugAppender.encoding" $encoding +modify_file "log4j.appender.infoAppender.encoding" $encoding +modify_file "log4j.appender.debugAppender.File" "$logs_path/nmsclient_debug.log" +modify_file "log4j.appender.infoAppender.File" "$logs_path/nmsclient_info.log" + +#permit +cd $INSTALL_DIR"/shell" +chmod 755 *.sh +cd $CUR_PRGDIR + +if [ -z "$(cat /etc/rc.local|grep $INSTALL_DIR"/shell/startup.sh")" ] +then + echo $INSTALL_DIR"/shell/startup.sh" >> /etc/rc.local +fi + +echo "" +echo "install successed..." +echo "please use [$INSTALL_DIR/shell/startup.sh] to run the program..." diff --git a/linuxinstall/readme.txt b/linuxinstall/readme.txt new file mode 100644 index 0000000..d8631d2 --- /dev/null +++ b/linuxinstall/readme.txt @@ -0,0 +1,59 @@ +NC--Linux下的安装文件结构: + +|--NC_install +| |--autoinstall.sh +| |--install.sh +| |--bin +| | |--cer +| | | |--client_ks +| | | |--client_ts +| | |--fileComment.jar +| | |--nmsclient.jar +| |--conf +| | |--jvm.conf +| | |--log4j.properties +| | |--myconfig.properties +| | |--version.properties +| |--jre_install +| | |--jre-6u45-linux-i586.bin +| | |--jre-6u45-linux-x64.bin +| |--lib +| | |--ant.jar +| | |--commons-beanutils-1.7.jar +| | |--commons-collections.jar +| | |--commons-io.jar +| | |--commons-lang.jar +| | |--commons-logging.jar +| | |--ezmorph-1.0.4.jar +| | |--java-unrar-0.3.jar +| | |--javatar-2.5.jar +| | |--jreloader.jar +| | |--json-lib-2.2.2-jdk15.jar +| | |--junit.jar +| | |--log4j-1.2.15.jar +| | |--ostermillerutils_1_07_00.jar +| | |--sigar.jar +| | |--libsigar-amd64-linux.so +| | |--libsigar-x86-linux.so +| |--shell +| | |--check_userpass.sh +| | |--execCmdBySu.sh +| | |--nmsagent.sh +| | |--nmsclient_shouhu.sh +| | |--restart.sh +| | |--shutdown.sh +| | |--startup.sh + + +脚本说明: + +1、安装脚本install.sh: + 先检查JDK是否安装且Java版本是否适合,来选择是否安装自带的JRE。 + 若需自带安装,则判断系统的位数,相应安装32位JDK或64位JDK。 + JDK安装目录为/home/nms/jre1.6.0_45, 并建软连接/home/nms/nmsjdk + 若系统已安装相应版本的JDK,则建连接/home/nms/nmsjdk + +2、自动安装脚本autoinstall.sh + JDK的检查逻辑与install.sh一样,只是所有参数都按默认值,不需人工交互,并安装完成后自动启动。 + +3、shell目录下,脚本nmsagent.sh和datacontroller.sh,不检查JDK版本,只检查nmsjdk是否存在且nmsjdk/bin/Java命令能否正常使用 \ No newline at end of file diff --git a/linuxinstall/shell/check_userpass.sh b/linuxinstall/shell/check_userpass.sh new file mode 100644 index 0000000..6e6dc7d --- /dev/null +++ b/linuxinstall/shell/check_userpass.sh @@ -0,0 +1,47 @@ +#!/usr/bin/expect + +if {$argc!=3} { + send_user "usage: check_userpass.sh ip name password\n" + exit 1 +} + +set host [lindex $argv 0] +set user [lindex $argv 1] +set pass [lindex $argv 2] + +set isSend 0 +spawn ssh -t "${user}@${host}" + +while 1 { + expect { + "* (yes/no)*" {send "yes\r"} + "* *" { + send "${pass}\r" + set isSend 1 + } + "* password:*" { + send "${pass}\r" + set isSend 1 + } + "Permission denied" { + send_user "Not allowed\n" + exit 1 + } + "*~]" { + send_user "OK\n" + send "exit\r" + exit 0 + } + "Last login:*" { + send_user "OK\n" + send "exit\r" + exit 0 + } + default { + send_user "error\n" + exit 2 + } + } +} + + diff --git a/linuxinstall/shell/execCmdBySu.sh b/linuxinstall/shell/execCmdBySu.sh new file mode 100644 index 0000000..4a94436 --- /dev/null +++ b/linuxinstall/shell/execCmdBySu.sh @@ -0,0 +1,78 @@ +#!/usr/bin/expect + +if {$argc!=4&&$argc!=3} { + send_user "usage: execCmdBySu.sh resultFlag command name \[password\]\n" + exit 1 +} +# 0ִȡý1ִ&̨ +set resultFlag [lindex $argv 0] +set cmd [lindex $argv 1] +set user [lindex $argv 2] +set pass [lindex $argv 3] + +set timeout 30 +set flag 0 + +#رտ̨Ϣ +log_user 0 + +spawn whoami +expect "root" {set flag 1} + +# ִ${cmd}׷"echo $?",Ϊȡcmdеʵʽ, εصϢ +if {$resultFlag==0} { + spawn su - -c "${cmd};echo $?" ${user} + + #ǰ¼ûroot + if {$flag==0} { + expect { + "*" {send ${pass}\r} + "password*" {send ${pass}\r} + default { + send_error "error\n" + exit 2 + } + } + } + + #򿪿̨Ϣ + log_user 1 + + expect { + "* 벻ȷ*" {exit 1} + #----˴ĿΪܶȡ + eof {exit 0} + } + +} else { + spawn su - -c "${cmd}" ${user} + + #ǰ¼ûroot + if {$flag==0} { + expect { + "*" {send ${pass}\r} + "password*" {send ${pass}\r} + default { + send_error "error\n" + exit 2 + } + } + } + expect { + "* 벻ȷ*" {exit 1} + #----Ϊ&̨ + eof { + send_user "ok\n" + exit 0 + } + } +} +interact +exit 0 + + +#overlay chess +#overlay program args +#disconnect +#close -onexec 0 -i ${spawn_id} +#remove_nulls 1 \ No newline at end of file diff --git a/linuxinstall/shell/nmsagent.sh b/linuxinstall/shell/nmsagent.sh new file mode 100644 index 0000000..9450828 --- /dev/null +++ b/linuxinstall/shell/nmsagent.sh @@ -0,0 +1,260 @@ +#!/bin/sh + +# ----------------------------------------------------------------------------- +# Start/Stop Script for the NMS Client +# +# Environment Variable Prequisites +# +# NMSCLEINT_HOME May point at your Catalina "build" directory. +# +# NMSCLIENT_TASKDIR (Optional) Directory path location of taskresult directory +# Defaults to %NMSCLIENT_HOME%/task. +# +# NMSCLIENT_TMPDIR (Optional) Directory path location of temporary directory +# the JVM should use (java.io.tmpdir). Defaults to +# $NMSCLIENT_HOME/temp. +# +# JAVA_HOME Must point at your Java Development Kit installation. +# Required to run the with the "debug" argument. +# +# ----------------------------------------------------------------------------- +# resolve links - $0 may be a softlink +PRG="$0" + +#OS_TYPE=$( lsb_release -d| cut -d: -f2| cut -f2 ) +#echo $OS_TYPE +while [ -h "$PRG" ]; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`/"$link" + fi +done + +# Get standard environment variables +PRGDIR=`dirname "$PRG"` + +# Only set NMSCLEINT_HOME if not already set +[ -z "$NMSCLEINT_HOME" ] && NMSCLEINT_HOME=`cd "$PRGDIR/.." ; pwd` +cd "$NMSCLEINT_HOME"/shell + +if [ -z "$NMSCLIENT_TMPDIR" ] ; then + NMSCLIENT_TMPDIR="$NMSCLEINT_HOME"/temp +fi +if [ ! -d $NMSCLIENT_TMPDIR ] + then + mkdir $NMSCLIENT_TMPDIR +fi + +if [ -n "$4" ]; then + NMSCLIENT_TASKDIR=`dirname "$4"` +fi +if [ -z "$NMSCLIENT_TASKDIR" ] ; then + NMSCLIENT_TASKDIR="$NMSCLEINT_HOME"/task +fi + + +# -------- check jdk +# check nmsjdk +NMS_HOME=`cd "$NMSCLEINT_HOME/.." ; pwd` +cd "$NMSCLEINT_HOME"/shell +NMS_JDK="$NMS_HOME"/nmsjdk +if [ ! -e "$NMS_JDK" ] + then + echo "$NMS_JDK not exist" + exit 0 +fi +# check java -version +javaversion=`$NMS_JDK/bin/java -version 2>&1|grep "java version"` +if [ ! -n "$javaversion" ] + then + echo "$NMS_JDK cannot use, please install" + exit 0 +fi + +# -------- set jdk path +export JAVA_HOME=$NMS_JDK +export CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar +export PATH=$JAVA_HOME/bin:$PATH + +temp=$CLASSPATH +#setting libs path +libs="$NMSCLEINT_HOME"/lib/* +append(){ + temp=$temp":"$1 +} +for file in $libs; do + append $file +done +jars="$NMSCLEINT_HOME"/bin/* +for file in $jars; do + append $file +done +export NC_CLASSPATH=$temp:.:$NMSCLEINT_HOME/conf +export LD_LIBRARY_PATH=$NMSCLEINT_HOME/lib +export LANG=zh_CN.UTF-8 + +# Bugzilla 37848: When no TTY is available, don't output to console +have_tty=0 +if [ "`tty`" != "not a tty" ]; then + have_tty=1 +fi + +# ----- Execute The Requested Command ----------------------------------------- + +# Bugzilla 37848: only output this if we have a TTY +if [ $have_tty -eq 1 ]; then + echo "Using NMSCLEINT_HOME: $NMSCLEINT_HOME" + echo "Using NMSCLIENT_TMPDIR: $NMSCLIENT_TMPDIR" + echo "Using JAVA_HOME: $JAVA_HOME" + echo "Using CLASSPATH: $NC_CLASSPATH" +fi + +# ---- get jvm param +jvmconf_file=$NMSCLEINT_HOME"/conf/jvm.conf" +if [ -f $jvmconf_file ] + then + #sed -n '/Xmx=/p' $jvmconf_file | sed 's/Xmx=//g' + XmsOpt=`sed -n '/-Xms/p' $jvmconf_file` + XmxOpt=`sed -n '/-Xmx/p' $jvmconf_file` + JAVA_OPTS="$XmsOpt $XmxOpt -XX:+UseParNewGC" +else + JAVA_OPTS="-Xms64m -Xmx128m -XX:+UseParNewGC" +fi + +program="com.nis.nmsclient.NmsClient" +name="NmsClient" + +proc_id= + +# handler agent upgrade result +handleTask() +{ + if [ -d "$NMSCLIENT_TASKDIR" ] + then + cd $NMSCLIENT_TASKDIR + for i in *.upgrade;do mv "$i" "${i%.upgrade}.result";done >/dev/null 2>&1 + cd "$NMSCLEINT_HOME"/shell + fi +} +writePid() +{ + ps aux|grep java|grep $program|grep -v grep|awk '{print $2}' > $NMSCLIENT_TMPDIR/agentPid.temp +} +getPid() +{ + unset proc_id + proc_id=`ps aux|grep java|grep $program|grep -v grep|awk '{print $2}'` +} +shouhu_proc="$NMSCLEINT_HOME"/shell/nmsclient_shouhu.sh +stopShouhuProc() +{ + shouhu_proc_id=`ps aux|grep $shouhu_proc|grep -v grep|awk '{print $2}'` + if [ -n "$shouhu_proc_id" ] + then + echo "kill shouhu process ....." + kill -9 $shouhu_proc_id + fi +} +startShouhuProc() +{ + shouhu_proc_id=`ps aux|grep $shouhu_proc|grep -v grep|awk '{print $2}'` + if [ ! -n "$shouhu_proc_id" ] + then + echo "start shouhu process ....." + nohup $shouhu_proc $NMSCLIENT_TASKDIR >/dev/null & + fi +} +if [ "$1" = "start" ] ; then + getPid + if [ -n "$proc_id" ] + then + echo "$name already running......" + else + nohup java $JAVA_OPTS -classpath $NC_CLASSPATH $program >/dev/null & + sleep 3 + getPid + if [ -n "$proc_id" ] + then + echo "$name start success!!!!!" + writePid + else + echo "$name start error!!!!!" + fi + handleTask + fi +elif [ "$1" = "stop" ]; then + getPid + if [ -n "$proc_id" ] + then + stopShouhuProc + sleep 1 + echo "$name is start, now kill......" + kill -9 $proc_id + writePid + echo "$name kill ok !!!!!!!!!!!!!" + else + echo "$name is not start!!!!!!!!!!!" + fi +elif [ "$1" = "restart" ] ; then + getPid + if [ -n "$proc_id" ] + then + echo "$name is start, now restart......" + stopShouhuProc + sleep 1 + startShouhuProc + kill -9 $proc_id + getPid + if [ -n "$proc_id" ] + then + echo "$name stop error!!!!!!!!!!" + handleTask + exit 1 + fi + else + echo "$name is not start, now start......" + fi + copyError= + if [ -n "$2" ] ; then + srcFile=$2 + updateFile=/dev/null + if [ -d "$2" ]; then + srcFile="$2"/* + fi + if [ -n "$4" ]; then + updateFile=$4 + fi + if [ -n "$3" ]; then + unalias cp >/dev/null 2>&1 + cp -rvf $srcFile $3 >>$updateFile 2>&1 ||copyError=1 + fi + rm -rf $2 >/dev/null 2>&1 + fi + if [ -n "$copyError" ] + then + #----copy error + handleTask + else + #--------copy right, start proc + nohup java $JAVA_OPTS -classpath $NC_CLASSPATH $program >/dev/null & + sleep 3 + getPid + if [ -n "$proc_id" ] + then + writePid + else + echo "$name restart error!!!!!!!!!!" + handleTask + fi + fi + +else + echo "Usage: nmsagent.sh ( commands ... )" + echo "commands:" + echo " start Start $name in a separate window" + echo " restart ReStart $name in a separate window" + echo " stop Stop $name" +fi diff --git a/linuxinstall/shell/nmsclient_shouhu.sh b/linuxinstall/shell/nmsclient_shouhu.sh new file mode 100644 index 0000000..821884f --- /dev/null +++ b/linuxinstall/shell/nmsclient_shouhu.sh @@ -0,0 +1,55 @@ +#!/bin/sh + +# resolve links - $0 may be a softlink +PRG="$0" + +while [ -h "$PRG" ]; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`/"$link" + fi +done + +# Get standard environment variables +PRGDIR=`dirname "$PRG"` + +# Only set NMSCLEINT_HOME if not already set +[ -z "$NMSCLEINT_HOME" ] && NMSCLEINT_HOME=`cd "$PRGDIR/.." ; pwd` +cd "$NMSCLEINT_HOME"/shell + +NC_TASKDIR="$1" +log_file="$NMSCLEINT_HOME"/temp/job.log +echo "NC_TASKDIR:$NC_TASKDIR" >> $log_file + +#count=1 +while [ 1 -eq 1 ] +do + sleep 50 + if [ `ps -ef | grep NmsClient | grep -v grep | wc -l` -lt 1 ] + then + echo -n "Down at:" >> $log_file + date >> $log_file + # ---------- handler agent upgrade result + if [ -d "$NC_TASKDIR" ] + then + cd $NC_TASKDIR + for i in *.upgrade;do mv "$i" "${i%.upgrade}.result";done >>$log_file 2>&1 + cd "$NMSCLEINT_HOME"/shell + fi + # --------- start NC + "$NMSCLEINT_HOME"/shell/startup.sh + echo "NmsClient start...." >>$log_file + fi + sleep 1 + #count=$count+1 + + #if [ count -eq 900 ] + #then + # jpid=`ps -ef | grep java | grep -v grep | cut -c0-5` + # kill -9 $jpid + # count=1 + #fi +done \ No newline at end of file diff --git a/linuxinstall/shell/restart.sh b/linuxinstall/shell/restart.sh new file mode 100644 index 0000000..f3c288d --- /dev/null +++ b/linuxinstall/shell/restart.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +# ----------------------------------------------------------------------------- +# Retart Script for the NMS Client +# +# ----------------------------------------------------------------------------- + +# resolve links - $0 may be a softlink +PRG="$0" + +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`/"$link" + fi +done + +PRGDIR=`dirname "$PRG"` +EXECUTABLE=nmsagent.sh + +if [ ! -x "$PRGDIR"/"$EXECUTABLE" ]; then + echo "Cannot find $PRGDIR/$EXECUTABLE" + echo "This file is needed to run this program" + exit 1 +fi + +exec "$PRGDIR"/"$EXECUTABLE" restart $1 $2 $3 "$@" \ No newline at end of file diff --git a/linuxinstall/shell/shutdown.sh b/linuxinstall/shell/shutdown.sh new file mode 100644 index 0000000..bc5ecc9 --- /dev/null +++ b/linuxinstall/shell/shutdown.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +# ----------------------------------------------------------------------------- +# Stop Script for the NMS Client +# +# ----------------------------------------------------------------------------- + +# resolve links - $0 may be a softlink +PRG="$0" + +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`/"$link" + fi +done + +PRGDIR=`dirname "$PRG"` +EXECUTABLE=nmsagent.sh + +if [ ! -x "$PRGDIR"/"$EXECUTABLE" ]; then + echo "Cannot find $PRGDIR/$EXECUTABLE" + echo "This file is needed to run this program" + exit 1 +fi + +exec "$PRGDIR"/"$EXECUTABLE" stop "$@" \ No newline at end of file diff --git a/linuxinstall/shell/startup.sh b/linuxinstall/shell/startup.sh new file mode 100644 index 0000000..a28c64a --- /dev/null +++ b/linuxinstall/shell/startup.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +# ----------------------------------------------------------------------------- +# Start Script for the NMS Client +# +# ----------------------------------------------------------------------------- + +# resolve links - $0 may be a softlink +PRG="$0" + +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`/"$link" + fi +done + +PRGDIR=`dirname "$PRG"` +EXECUTABLE=nmsagent.sh + +if [ ! -x "$PRGDIR"/"$EXECUTABLE" ]; then + echo "Cannot find $PRGDIR/$EXECUTABLE" + echo "This file is needed to run this program" + exit 1 +fi + +exec "$PRGDIR"/"$EXECUTABLE" start "$@" \ No newline at end of file diff --git a/src/com/nis/nmsclient/NmsClient.java b/src/com/nis/nmsclient/NmsClient.java new file mode 100644 index 0000000..101a4c6 --- /dev/null +++ b/src/com/nis/nmsclient/NmsClient.java @@ -0,0 +1,549 @@ +package com.nis.nmsclient; + +import java.io.File; +import java.io.IOException; +import java.util.Calendar; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +import org.apache.log4j.Logger; + +import com.nis.nmsclient.common.Common; +import com.nis.nmsclient.common.Contants; +import com.nis.nmsclient.common.SysConfig; +import com.nis.nmsclient.config.DetecConfReqHandle; +import com.nis.nmsclient.model.AlarmInfo; +import com.nis.nmsclient.model.SetInfo; +import com.nis.nmsclient.thread.WritePidThread; +import com.nis.nmsclient.thread.alarm.AlarmThread; +import com.nis.nmsclient.thread.alarm.AlarmUtil; +import com.nis.nmsclient.thread.alarm.ErrorCode; +import com.nis.nmsclient.thread.socket.CommonSocket; +import com.nis.nmsclient.thread.socket.SSLClient; +import com.nis.nmsclient.thread.socket.SSLServer; +import com.nis.nmsclient.thread.task.TaskResultOper; +import com.nis.nmsclient.thread.timer.DelLocalFileThread; +import com.nis.nmsclient.thread.upload.DataSendThread; +import com.nis.nmsclient.util.FileUtil; +import com.nis.nmsclient.util.ProcessUtil; +import com.nis.nmsclient.util.Utils; + +/** + * NMSClient 程序启动主方法类 + */ +public class NmsClient{ + static Logger logger = Logger.getLogger(NmsClient.class); + // 监测设置信息,初始化完成后清空 + public List setInfos = new LinkedList(); + // 监测设置的报警字段设置信息,初始化完成后清空 + public Map> alarmInfos = new HashMap>(); + private int testGap = 60; //单位:秒 + + static{ +// Thread.currentThread().setName("NMSClient主程序"); + Thread.currentThread().setName("NMSClient Main Program"); + } + + /** + * NMSClient 程序启动入口 + */ + public static void main(String[] args) { + logger.info("------- NMSClient 启动开始------------"); + + //NMSClient进程停止保存缓存操作 + doShutDownWork(); + + /** + * 启动通信程序, 如果端口已存在即SSLServer创建失败,退出程序 + */ + //通讯端口放在第一步,为了确保初始化配置不成功或个数为0时 新建任务下发、DC收集数据、握手等操作 能正常执行 + //注意:要在通讯程序中判断SeqId是否为空,为空 则只接收握手通信、收集数据通信,其他的通信都抛弃 + SSLServer sslServer = null; + try { + sslServer = new SSLServer(); + } catch (IOException e) { + TaskResultOper.handerAgentUpgradeResult(false); + logger.error("NMSClient Program termination:" + e.getMessage()); + AlarmUtil.sendNMSErrorMsg(ErrorCode.ProtListenerError, Utils.getLocalIp(), "i18n_client.NmsClient.ncCommunicatePortErr_n81i"); + System.exit(0); + } +// Thread server = new Thread(sslServer, "通讯线程"); + Thread server = new Thread(sslServer, "Communication Thread"); + server.start(); + + /** + * 启动守护进程 + */ + try { + String os = System.getProperty("os.name"); + String cmd = ""; + String procSearchKey = null; + if (os.startsWith("Windows")) { + String homePath = new File(Contants.SYSTEM_PATH).getParent();//NC布署路径 + cmd = homePath + File.separator + "script" + File.separator + "nmsclient_shouhu.bat"; + procSearchKey = "nmsclient_shouhu.bat"; + } else if (os.startsWith("Linux")) { + cmd = Contants.SYSTEM_PATH + File.separator + "nmsclient_shouhu.sh"; + procSearchKey = "nmsclient_shouhu.sh"; + } + Object[] objArr = ProcessUtil.checkPidAndGetPid(null, procSearchKey); + int isExistFlag = Integer.parseInt(objArr[0].toString()); + if(isExistFlag == 0){// 守护进程不存在,启动 + logger.info("正在启动守护进程..."); + ProcessUtil.runExec(cmd, new String[]{Contants.localTaskResultPath}, null, null, true); + objArr = ProcessUtil.checkPidAndGetPid(null, procSearchKey); + isExistFlag = Integer.parseInt(objArr[0].toString()); + if(isExistFlag != 0){ + logger.info("守护进程 启动成功"); + }else{ + logger.info("守护进程 启动失败"); + AlarmUtil.sendNMSErrorMsg(ErrorCode.DeamonNotExist, Utils.getLocalIp(), "i18n_client.NmsClient.ncDeamonStartFail_n81i"); + } + }else { + logger.info("守护进程 已存在,无需再启动"); + } + + } catch (Exception e) { + logger.error("Start the daemon exception", e); + AlarmUtil.sendNMSErrorMsg(ErrorCode.DeamonNotExist, Utils.getLocalIp(), "i18n_client.NmsClient.ncDeamonStartException_n81i," + e.getMessage()); + } + + /** + * 相关业务操作入口 + */ + new NmsClient().run(); + + } + + public void run() { + //执行写PID线程 + Common.service.submit(new WritePidThread()); + + // 2013-3-8 由于初始化监测配置个数为0时不断重新获取,致使任务初始化无法执行,先将任务与监测配置分开执行 + // 为了将初始化监测配置放于任务之后,所以在开始执行之前,先与DC握手通讯,以保证通讯正常 + while (true) { + try { + //与Server通信 + Future serFuture = Common.service.submit(new SSLClient( + Thread.currentThread().getName(), + CommonSocket.REQ_HAND_SHAKE, null)); + if (Contants.isSucessByResult((String) serFuture.get())) { + break; + } + } catch (Exception e) { + logger.error("Handshake communication abnormality:" + Utils.printExceptionStack(e)); + } + + try { + Thread.sleep(1000 * testGap);// 如果握手失败,让当前线程暂停N秒,再重试 + } catch (InterruptedException e) { + logger.error(Utils.printExceptionStack(e)); + continue; + } + } + + // 获取本机唯一标识 + initUUID(); + // 检查本机操作系统和IP是否变更 + checkLocalOperSystemAndIp(); + + /**************************** 任务部分处理操作 ***************************/ + // 处理Agent自身升级时的执行结果文件 + TaskResultOper.handerAgentUpgradeResult(true); + // 发送所有之前上发失败的任务结果 + TaskResultOper.initSendAllTaskResult(); + + // 初始化执行中的任务 + if (Contants.DEBUG_INIT_TASK_FLAG == 0) { +// Common.scheduled.schedule(new SSLClient("初始化任务", + Common.scheduled.schedule(new SSLClient("Initialization Task", + CommonSocket.REQ_INIT_TASK, null), + Contants.COMMON_TASK_INIT_DELAY_MINUTES, TimeUnit.MINUTES); + } + // 定时上传发送失败的任务结果 + /*if (Contants.DEBUG_TASKRESULT_FLAG == 0) { + Common.scheduled.scheduleWithFixedDelay(new Runnable() { + public void run() { + Thread.currentThread().setName("上传任务结果"); + TaskResultOper.initSendAllTaskResult(); + } + }, 0, Contants.COMMON_TASK_RESULT_SEND_MINUTES, TimeUnit.MINUTES); + }*/ + // 定时上传发送失败的回传文件 + /*if (Contants.DEBUG_TASKRETURN_FLAG == 0) { + Common.scheduled.scheduleWithFixedDelay(new Runnable() { + public void run() { + Thread.currentThread().setName("回传文件"); + new TaskReturnHandle().sendAllTaskReturnFile(); + } + }, 0, Contants.COMMON_TASK_RESULT_SEND_MINUTES, TimeUnit.MINUTES); + }*/ + // 定时清理内存中已完成的任务 + Common.scheduled.scheduleWithFixedDelay(new Runnable() { + public void run() { +// Thread.currentThread().setName("清理已完成任务"); + Thread.currentThread().setName("Clean Up The Completed Task"); + // == 1、针对结果文件过多时打包上传未完成的文件 + File taskDir = new File(Contants.localTaskPath); + if (taskDir.exists()) { + // ----取所有未上传完成的Zip文件 + File[] zipArr = FileUtil.getFilesEndWith(taskDir, ".zip"); + // 若存在未上传完成的ZIP结果文件,则不清理内存中的任务 + if (zipArr.length > 0) { + return; + } + } + + // == 2、检查当前结果文件数量 + File resultDir = new File(TaskResultOper.getTaskResultPath()); + if(resultDir.exists()){ + File[] fileArr = FileUtil.getFilesEndWith(resultDir, Contants.TASK_RESULT_FILE_SUFFIX); + // 若存在未上传的结果文件,则不清理内存中的任务 + if(fileArr.length > 0){ + return; + } + } + + // -- 清理已完成的任务,待考虑 以后定时清理方案 + Common.removeCancelAndDoneTaskFuture(); + } + }, Contants.COMMON_TASK_CLEAR_HOURS, Contants.COMMON_TASK_CLEAR_HOURS, TimeUnit.HOURS); + + /**************************** 定时清理本地文件操作 ***************************/ + // 定时删除本地生成的文件 + if (Contants.DEBUG_DELFILE_FLAG == 0) { + //2012-4-28 将所有删除文件的线程合并为一个,取设置的所有清理文件间隔中的最小值作为检查间隔 + //2012-12-17 第一次执行删除文件时间,不是启动立即删除,设置延迟到启动之后的第一个凌晨0点 + Calendar cal = Calendar.getInstance(); + cal.add(Calendar.DAY_OF_MONTH, 1); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + long delay = cal.getTimeInMillis()-System.currentTimeMillis(); +// Common.scheduled.scheduleAtFixedRate(new DelLocalFileThread("删除文件"), delay, + Common.scheduled.scheduleAtFixedRate(new DelLocalFileThread("Delete Files"), delay, + getMinCheckPeriod() * 60 * 60 * 1000, TimeUnit.MILLISECONDS); + } + + /**************************** 监测配置信息处理操作 ***************************/ + // 初始化监测配置信息 + initDetecConfig(); + // 启动三方监测程序 + if (Contants.DEBUG_PLUGIN_FLAG == 0) { + //-------------初始化三方监测 start + for (SetInfo setInfo : setInfos) { + // 缓存三方监测配置信息,用于合并临时结果文件 + Common.putPluginDetecSetInfo(setInfo.getId(), setInfo); + + if (!Common.COMMON_SYS_SETINFO.equals(setInfo.getIsSchedule())) { // 第三方且由Agent启动 + Common.startPluginDetec(setInfo); + } + } + //-------------初始化三方监测 end + } + //启动预设监测程序 + if (Contants.DEBUG_SYSDETECT_FLAG == 0) { + //-------------初始化预设监测 start + for (SetInfo setInfo : setInfos) { + if (Common.COMMON_SYS_SETINFO.equals(setInfo.getIsSchedule())) {// 判断如果是系统预设类型 + Common.addOrUpdateSysDetec(setInfo, alarmInfos + .get(setInfo.getId())); + } + } + //-------------初始化预设监测 end + } + + //启用监测主动上报 + if(Contants.DATA_SEND_THREAD_FLAG == 0){ + Common.scheduled.scheduleWithFixedDelay(new DataSendThread(Contants.DATA_SEND_THREAD_HOST, Contants.DATA_SEND_THREAD_PORT), (int)(Math.random()*Contants.DATA_SEND_THREAD_INTERVAL), Contants.DATA_SEND_THREAD_INTERVAL, TimeUnit.SECONDS); + logger.info("监测主动上报已成功添加到线程池"); + } + + // 启动上传数据程序 + /*if (Contants.DEBUG_UPLOADDATA_FLAG == 0) { + Common.scheduled.scheduleWithFixedDelay(new UploadDataThread("上传数据"), 1, + Contants.COMMON_UPLOAD_DATA_MINUTES, TimeUnit.MINUTES); + }*/ + // 启动主动报警程序 + if (Contants.DEBUG_ALARM_FLAG == 0) { +// Common.scheduled.scheduleAtFixedRate(new AlarmThread("主动预警"), 1, + Common.scheduled.scheduleAtFixedRate(new AlarmThread("Active Early Warning"), 1, + Contants.COMMON_UPLOAD_DATA_MINUTES, TimeUnit.MINUTES); + } + + //清空变量 + setInfos.clear(); + setInfos = null; + alarmInfos.clear(); + alarmInfos = null; + } + + /** + * 第一次布署NMSAgent时,初始化本机唯一标志 + */ + public void initUUID() { + if (Contants.AGENT_HOST_UUID == null) {// 第一次布署Agent + while (true) { + String uuid = null; + try { + Future future = Common.service.submit(new SSLClient( +// "获取本机标识", CommonSocket.REQ_LOCAL_UUID, null)); + "Obtain The Local Identity", CommonSocket.REQ_LOCAL_UUID, null)); + String msg = (String) future.get(); + if (Contants.isSucessByResult(msg)) { + // dc发送的数据格式为 uuid:::localIp + String[] result = Contants.getDescByResult(msg).split( + ":::"); + uuid = result[0]; + String localIp = result[1]; + logger.info("本机标识ID:" + uuid); + if (!(uuid == null || "".equals(uuid) + || "null".equals(uuid) || localIp == null + || "".equals(localIp) || "null".equals(localIp))) { + + SysConfig.setUUIDValue(uuid); + //根据ip地址获取端口名称 + String name = Utils.getNetInterfaceNameByIp(localIp); + //将端口名称写入配置文件 + SysConfig.setInterfaceNameValue(name); + break; + } + } + } catch (Exception e) { + logger.error("Get the unique identity of the native or IP port name exception:" + Utils.printExceptionStack(e)); + } + try { + logger.debug((1000 * testGap ) +"s 后重试"); + Thread.sleep(1000 * testGap);// 如果获取失败,让当前线程暂停N秒,再重试 + } catch (InterruptedException e) { + logger.error(Utils.printExceptionStack(e)); + } + } + } + } + /** + * 每次启动时检查本机操作系统类型和IP是否有变更,若有,则将最新信息写入文件并发送信息到Server, + * 由Server端根据SeqID更新所有相关节点信息 + */ + public void checkLocalOperSystemAndIp() { + // ---- 取本机相关信息 + String operateSysType = getOperateSysType(); + String localIp = Utils.getIpAddressByEthName(Contants.AGENT_INTERFACE_NAME_KEY); + + logger.info("本机通讯IP:" + localIp); + if (localIp != null && !"".equals(localIp) && !"null".equals(localIp)) { + // ----- 与原有信息比较 + if (Contants.AGENT_OPERATE_SYSTEM == null + || Contants.AGENT_LOCAL_IP == null + || !operateSysType.equals(Contants.AGENT_OPERATE_SYSTEM) + || !localIp.equals(Contants.AGENT_LOCAL_IP)) { + // 若有变更,则将本机系统和IP写入文件,再发送到Server + SysConfig.setUUIDValue(operateSysType, localIp); + // 发送UUID、SystemType、LocalIp到Server + String sendMsg = Contants.AGENT_HOST_UUID + + Contants.COMMON_MSG_SEPRATOR + + Contants.AGENT_OPERATE_SYSTEM; + try { + Future future1 = Common.service.submit(new SSLClient( +// "信息变更", CommonSocket.REQ_LOCAL_CHANGE, sendMsg)); + "Information Change", CommonSocket.REQ_LOCAL_CHANGE, sendMsg)); + String resultMsg = (String) future1.get(); + String descMsg = Contants.getDescByResult(resultMsg); + if (!Contants.isSucessByResult(resultMsg)) { + if (descMsg == null || "".equals(descMsg) + || "null".equals(descMsg)) { +// descMsg = "信息变更出现问题,可能存在重复IP,请手动检查"; + descMsg = "Information changes may occur. Duplicate IP may exist. Please check manually."; + } + logger.error("Failure of information change:" + descMsg); + } else if (descMsg != null && !"".equals(descMsg)) { + logger.info("信息变更:" + descMsg); + } + } catch (Exception e) { + logger.error("Information change:" + Utils.printExceptionStack(e)); + } + } + } + } + + + /** + * 获取本机操作系统类型 + * + * @return 1代表linux ;2代表windows; “” 为其它 + */ + public static String getOperateSysType() { + String operateSysType = null; + String os = System.getProperty("os.name"); + if (os.startsWith("Windows")) { + operateSysType = "2"; + } else if (os.startsWith("Linux")) { + operateSysType = "1"; + } else { + operateSysType = ""; + } + return operateSysType; + } + + +// /** +// * 第一次布署NMSAgent时,初始化本机唯一标志 +// */ +// public void initUUID(){ +// if(Contants.AGENT_HOST_UUID == null){//第一次布署Agent +// while (true) { +// String uuid = null; +// try { +// Future future = Common.service.submit(new SSLClient( +// "获取本机标识", CommonSocket.REQ_LOCAL_UUID, null)); +// String msg = (String) future.get(); +// if (Contants.isSucessByResult(msg)) { +// uuid = Contants.getDescByResult(msg); +// logger.info("本机标识ID:" + uuid); +// if(uuid != null && !"".equals(uuid) && !"null".equals(uuid)){ +// SysConfig.setUUIDValue(uuid); +// break; +// } +// } +// } catch (Exception e) { +// logger.error("获取本机唯一标识异常:" + Utils.printExceptionStack(e)); +// } +// +// try { +// Thread.sleep(1000 * testGap);// 如果获取失败,让当前线程暂停N秒,再重试 +// } catch (InterruptedException e) { +// logger.error(Utils.printExceptionStack(e)); +// } +// } +// } +// } +// +// /** +// * 每次启动时检查本机操作系统类型和IP是否有变更,若有,则将最新信息写入文件并发送信息到Server,由Server端根据SeqID更新所有相关节点信息 +// */ +// public void checkLocalOperSystemAndIp(){ +// //---- 取本机相关信息 +// String operateSysType = null; +// String os = System.getProperty("os.name"); +// if (os.startsWith("Windows")) { +// operateSysType = "2"; +// }else if (os.startsWith("Linux")){ +// operateSysType = "1"; +// }else{ +// operateSysType = ""; +// } +// String localIp = Utils.getLocalIp(); +// //----- 与原有信息比较 +// if (Contants.AGENT_OPERATE_SYSTEM == null +// || Contants.AGENT_LOCAL_IP == null +// || !operateSysType.equals(Contants.AGENT_OPERATE_SYSTEM) +// || !localIp.equals(Contants.AGENT_LOCAL_IP)) { +// //若有变更,则将本机系统和IP写入文件,再发送到Server +// SysConfig.setUUIDValue(operateSysType, localIp); +// //发送UUID、SystemType、LocalIp到Server +// String sendMsg = Contants.AGENT_HOST_UUID +// + Contants.COMMON_MSG_SEPRATOR +// + Contants.AGENT_OPERATE_SYSTEM; +// try { +// Future future = Common.service.submit(new SSLClient("信息变更", +// CommonSocket.REQ_LOCAL_CHANGE, sendMsg)); +// String resultMsg = (String) future.get(); +// String descMsg = Contants.getDescByResult(resultMsg); +// if (!Contants.isSucessByResult(resultMsg)) { +// if(descMsg == null || "".equals(descMsg) || "null".equals(descMsg)){ +// descMsg = "信息变更出现问题,可能存在重复IP,请手动检查"; +// } +// logger.error("信息变更失败:" + descMsg); +// }else if(descMsg!=null && !"".equals(descMsg)){ +// logger.info("信息变更:" + descMsg); +// } +// } catch (Exception e) { +// logger.error("信息变更:" + Utils.printExceptionStack(e)); +// } +// } +// } + + /** + * 请求获得初始化监测配置信息: 获取失败或获取配置个数为0,则不断循环获取 + */ + public void initDetecConfig(){ + while (true) { + try { + Future future = Common.service.submit(new SSLClient( +// "初始化监测配置", CommonSocket.REQ_INIT_CONFIG, null)); + "Initialization Of Monitoring Configuration", CommonSocket.REQ_INIT_CONFIG, null)); + String msg = (String) future.get(); + if (Contants.isSucessByResult(msg)) { + msg = Contants.getDescByResult(msg); + new DetecConfReqHandle().handlerConfigByInit(msg, setInfos, alarmInfos); + logger.info("初始化监测配置个数:" + setInfos.size()); + if(setInfos.size()>0){ + break; + } + + } + } catch (Exception e) { + logger.error("Initialization of monitoring configuration exceptions:" + Utils.printExceptionStack(e)); + } + + try { + Thread.sleep(1000 * testGap);//如果初始化失败,让当前线程暂停N秒,再重试 + } catch (InterruptedException e) { + logger.error(Utils.printExceptionStack(e)); + } + } + } + + /** + * 取设置的所有清理文件间隔中的最小值, 单位:小时 + */ + public int getMinCheckPeriod(){ + int period = Contants.COMMON_DEL_DATA_HOURS; + period = period < Contants.COMMON_DEL_LOG_DAYS * 24 ? period + : Contants.COMMON_DEL_LOG_DAYS * 24; + period = period < Contants.COMMON_DEL_TEMP_DAYS * 24 ? period + : Contants.COMMON_DEL_TEMP_DAYS * 24; + period = period < Contants.COMMON_DEL_UPGRADEFILE_DAYS * 24 ? period + : Contants.COMMON_DEL_UPGRADEFILE_DAYS * 24; + logger.debug("=========del file period=" + period); + + return period; + } + + + /** + * 进程停用时,触发该事件,将缓存数据存入硬盘 + * 在NC侧 当前情况是当NMSClient服务停止时无需做操作,因为NC启动的时候NC会将执行失败的任务结果发送给DC(TaskResultOper.initSendAllTaskResult()), + * 再收集DC的任务,不会有数据丢失。 + * + * 暂时无需做操作,先提供退出触发的机制,供后续使用 + * + * @author jinshujuan Jul 15, 2013 + * @version 1.0 + */ + public static void doShutDownWork() { + logger.info("注册程序退出事件"); + Runtime.getRuntime().addShutdownHook(new Thread() { + public void run() { + try { +// Thread.currentThread().setName("退出NMSClient,缓存数据清理线程"); + Thread.currentThread().setName("Exit NMSClient, Caching Data Cleaning Thread"); + logger.info("停止NMSClient,处理缓存数据。。。"); + //清理缓存数据Common类控制 + //logger.info("清空缓存"); + logger.info("停止NMSClient,处理缓存数据 完成"); + } catch (Exception ex) { + logger.error("Stop NMSClient, cache data entry anomalies, cache data to disk.", ex);//1.全部入库,入库异常时存盘 或 2.全部存盘,下次启动时入库 + //缓存数据存入硬盘操作 + //logger.info("保存缓存"); + logger.error("Stop NMSClient, cache data entry anomalies, cache data stored in hard disk to complete", ex);//1.全部入库,入库异常时存盘 或 2.全部存盘,下次启动时入库 + } + } + }); + } + +} diff --git a/src/com/nis/nmsclient/common/Common.java b/src/com/nis/nmsclient/common/Common.java new file mode 100644 index 0000000..7b56c16 --- /dev/null +++ b/src/com/nis/nmsclient/common/Common.java @@ -0,0 +1,453 @@ +package com.nis.nmsclient.common; + +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.filefilter.FalseFileFilter; +import org.apache.commons.io.filefilter.FileFilterUtils; +import org.apache.log4j.Logger; + +import com.nis.nmsclient.config.DetecConfOper; +import com.nis.nmsclient.model.AlarmInfo; +import com.nis.nmsclient.model.SetInfo; +import com.nis.nmsclient.thread.alarm.AlarmPO; +import com.nis.nmsclient.thread.alarm.AlarmUtil; +import com.nis.nmsclient.thread.plugin.StartPluginRun; +import com.nis.nmsclient.thread.task.LoopTaskThread; +import com.nis.nmsclient.util.ProcessUtil; +import com.nis.systeminfo.thread.GetInfoRun; + +public class Common { + static Logger logger = Logger.getLogger(Common.class); + + public static final String COMMON_SYS_SETINFO = "0"; + public static boolean NC_UPGRADE_FLAG = false; + + public static final ExecutorService service = Executors + .newFixedThreadPool(Contants.COMMON_THREAD_SOCKET_SIZE); // 通讯线程池 + public static final ScheduledExecutorService scheduled = Executors + .newScheduledThreadPool(Contants.COMMON_THREAD_SCHEDULE_SIZE); // 定时执行线程池 + + // 任务变更或取消控制集 object[1]=ScheduledFuture,object[2]=LoopTaskThread + private static Map taskFutureMap = Collections.synchronizedMap(new HashMap()); + // 主动告警信息: 主动报警线程使用 + private static Map alarmPOs = Collections.synchronizedMap(new HashMap()); + // 预置监测控制集 + private static Map> sysDetecFutrue = Collections.synchronizedMap(new HashMap>()); + // Agent定时启动的三方监测控制集 + private static Map> pluginDetecFutrue = Collections.synchronizedMap(new HashMap>()); + // 三方监测设置集 + private static Map pluginDetecSetInfoMap = new HashMap(); + // 监测信息报警相关信息(alarmInfo.setInfoId, alarmInfo) + public static Map> detecAlarmInfoMap = new HashMap>(); + + /** + * 缓存三方监测设置 + * + * @param key + * @param setInfo + * @param lastMergeFileDetecTime + */ + public static void putPluginDetecSetInfo(Long key, SetInfo setInfo) { + long planTime = (setInfo.getControlStartTime() != null) ? setInfo.getControlStartTime() : 0; + + // 初始化已合并的最后一个临时结果文件的监测时间,用于判断是否出现未生成监测数据的周期 + // 监测设置下发时,记录该监测的计划启动时间 + // NC重启时,记录当前时间(周期启动监测由NC控制,若NC重启后存在未合并的临时结果,忽略该时间段内未生成监测数据的周期) + if(setInfo.getLastMergeDetecTime() == null) { + setInfo.setLastMergeDetecTime(Math.max(System.currentTimeMillis(), planTime)); + } + if(setInfo.getPlanCheckTime() == null || setInfo.getPlanCheckTime().longValue() == 0) { + // GetRunInfo.startTime + setInfo.setPlanCheckTime(System.currentTimeMillis()); + } + + pluginDetecSetInfoMap.put(key, setInfo); + } + + /** + * 获取三方监测设置集 + * + * @param key + * @return + */ + public static Collection getPluginDetecSetInfos() { + return pluginDetecSetInfoMap.values(); + } + + public static void putAllDetecAlarmInfo(Map> alarmMap) { + detecAlarmInfoMap.putAll(alarmMap); + } + + /** + * 监测信息报警相关信息 + * @param setInfoId + * @return + */ + public static List getDetecAlarmInfo(Long setInfoId) { + return detecAlarmInfoMap.get(setInfoId); + } + + /** + * 获取任务 + */ + public static ScheduledFuture getTaskFuture(Long key) { + synchronized (taskFutureMap) { + Object[] objects = taskFutureMap.get(key); + if (objects != null && objects.length > 0 && objects[0] != null) { + return (ScheduledFuture) objects[0]; + } else { + return null; + } + } + } + + /** + * 添加任务 + */ + public static void putTaskFuture(Long key, ScheduledFuture value, LoopTaskThread loopTask) { + synchronized (taskFutureMap) { + taskFutureMap.put(key, new Object[] { value, loopTask }); + logger.info("添加任务 id:" + key); + } + } + + /** + * 注销任务 + */ + public static void cancleTaskFuture(final Long key, long delayMs) { + scheduled.schedule(new Runnable() { + public void run() { + synchronized (taskFutureMap) { +// Thread.currentThread().setName("注销任务 id:" + key); + Thread.currentThread().setName("Write Off Task ID:" + key); + Object[] objects = taskFutureMap.get(key); + if (objects!=null && objects.length>0 && objects[0]!=null) { + ScheduledFuture future = (ScheduledFuture) objects[0]; + logger.info("任务状态: " + + ((future.isDone() || future + .isCancelled()) ? "已停止" : "运行中")); + if (objects.length > 1 && objects[1] != null) { + LoopTaskThread loopTask = (LoopTaskThread) objects[1]; + loopTask.cancle(); + } + future.cancel(true); + taskFutureMap.remove(key); + logger.info("注销成功"); + } else { + logger.info("任务不存在"); + } + + } + } + }, delayMs, TimeUnit.MILLISECONDS); + } + + /** + * 从全局变量移除执行完成或者取消的任务(每次在上传发送失败的结果时检查并移除) + */ + public static void removeCancelAndDoneTaskFuture() { + synchronized (taskFutureMap) { + Iterator iterator = taskFutureMap.keySet().iterator(); + while (iterator.hasNext()) { + Long key = iterator.next(); + Object[] objects = taskFutureMap.get(key); + if (objects != null && objects.length > 0) { + ScheduledFuture future = (ScheduledFuture) objects[0]; + if (future.isCancelled() || future.isDone()) { + iterator.remove(); + logger.info("任务控制集 移除 id:" + key + " 状态: " + + ((future.isDone() || future + .isCancelled()) ? "已停止" : "运行中")); + } + } else { + iterator.remove(); + logger.info("任务控制集 移除 id:" + key); + } + } + } + } + + /** + * 获取存放预警信息集 + */ + public static Map getAlarmPOs() { + synchronized (alarmPOs) { + return alarmPOs; + } + } + + /** + * 取消某一监测类型的主动预警 + */ + public static void removeAlarmPO(Long key) { + synchronized (alarmPOs) { + if (alarmPOs.containsKey(key)) { + AlarmPO alarmPO = alarmPOs.get(key); + alarmPOs.remove(key); + logger.info("主动预警集 移除 setId:" + key + " >> " + + alarmPO.getType() + "_" + alarmPO.getProcIden()); + } + } + } + + /** + * 添加或更新对某一监测类型的主动预警 + */ + public static void addOrUpdateAlarmPO(AlarmPO alarmPO) { + synchronized (alarmPOs) { + Long key = alarmPO.getId(); + String infoMsg = "添加"; + + if (alarmPOs.containsKey(key)) { + infoMsg = "更新"; + } + + alarmPOs.put(key, alarmPO); + + logger.info("主动预警集 " + infoMsg + " setId:" + key + " >> " + alarmPO.getType() + "_" + alarmPO.getProcIden()); + } + } + + /** + * 取得预设监测总数 + */ + public static int getSysDetecCount() { + synchronized (sysDetecFutrue) { + return sysDetecFutrue.size(); + } + } + + /** + * 停用预设监测 + */ + public static void stopSysDetec(SetInfo setInfo) { + synchronized (sysDetecFutrue) { + Long key = setInfo.getId(); +// String threadName = "预设监测_" + String threadName = "Presupposition Monitoring_" + + DetecConfOper.getFileName(setInfo.getCheckTypeName(), + setInfo.getProcessIden(), null); + + ScheduledFuture future = sysDetecFutrue.get(key); + if (future != null) { + future.cancel(true); + sysDetecFutrue.remove(key); + logger.info("预设监测线程 停用 setId:" + setInfo.getId() + " >> " + + threadName); + } + } + } + + /** + * 添加或更新系统预设监测 + * @param setInfo + * @param alarmInfos + */ + public static void addOrUpdateSysDetec(SetInfo setInfo, List alarmInfos) { + synchronized (sysDetecFutrue) { + Long key = setInfo.getId(); + String infoMsg = "添加"; + + ScheduledFuture future = sysDetecFutrue.get(key); + if (future != null) { + future.cancel(true); + sysDetecFutrue.remove(key); + + infoMsg = "更新"; + } + + long delay = 0; + Date startTime = new Date(); + if (setInfo.getPlanCheckTime() != null) { + try { + long gap = setInfo.getPlanCheckTime() - System.currentTimeMillis(); + if (gap > 0) { + delay = gap; + startTime = new Date(setInfo.getPlanCheckTime()); + } + } catch (Exception e) { + logger.error("Please check whether the next test time is set correctly!", e); + } + } + +// String threadName = "预设监测_" + String threadName = "Presupposition Monitoring_" + + DetecConfOper.getFileName(setInfo.getCheckTypeName(), + setInfo.getProcessIden(), null); + + future = Common.scheduled.scheduleAtFixedRate(new GetInfoRun( + threadName, setInfo, startTime, alarmInfos), delay, setInfo + .getCheckGap(), TimeUnit.MINUTES); + sysDetecFutrue.put(key, future); + + logger.info("预设监测线程 " + infoMsg + " setId:" + setInfo.getId() + " >> " + threadName); + } + } + + /** + * 启动三方监测 + */ + public static void startPluginDetec(SetInfo setInfo) { +// String threadName = "三方监测_" + String threadName = "Three Party Monitoring_" + + DetecConfOper.getFileName(setInfo.getCheckTypeName(), + setInfo.getProcessIden(), null); + + Common.scheduled.schedule(new StartPluginRun(setInfo, threadName), 0, + TimeUnit.MILLISECONDS); + + logger.info("三方监测 添加 setId:" + setInfo.getId() + " >> " + threadName); + } + + /** + * 添加定时启动的三方监测 + */ + public static void putPluginDetecFuture(Long key, ScheduledFuture future) { + synchronized (pluginDetecFutrue) { + pluginDetecFutrue.put(key, future); + } + } + + /** + * 停止定时启动的三方监测任务 + */ + public static void stopPluginDetecFuture(Long key, String threadName) { + synchronized (pluginDetecFutrue) { + ScheduledFuture future = pluginDetecFutrue.get(key); + if (future != null) { + future.cancel(true); + sysDetecFutrue.remove(key); + logger.info("三方监测 移除 setId:" + key + " >> " + threadName); + } + } + } + + /** + * 检查三方监测是否存在(NC周期启动、NC单次启动) + */ + public static boolean containPluginDetecFuture(Long key) { + ScheduledFuture future = pluginDetecFutrue.get(key); + return (future != null); + } + + /** + * 停用三方监测 + */ + public static void stopPluginDetec(SetInfo setInfo) { + // NC周期启动监测需要获取三方监测的关键字 + if("2".equals(setInfo.getIsControlStart())) { + generateCommandAndKeyword(setInfo); + } + + Long key = setInfo.getId(); +// String threadName = "三方监测_" + String threadName = "Three Party Monitoring_" + + DetecConfOper.getFileName(setInfo.getCheckTypeName(), + setInfo.getProcessIden(), null); + synchronized (pluginDetecFutrue) { + ScheduledFuture future = pluginDetecFutrue.get(key); + if (future != null) { + future.cancel(true); + sysDetecFutrue.remove(key); + logger.info("三方监测 移除 setId:" + setInfo.getId() + " >> " + threadName); + } + } + try { + // 检查PID + Object[] objArr = ProcessUtil.checkPidAndGetPid(setInfo.getProcessFile(), setInfo.getProcessSearchKeyCode()); + int isExistFlag = Integer.parseInt(objArr[0].toString()); + String pidInfo = objArr[1].toString(); + + if (isExistFlag == 0) {// 不存在 + logger.info("停用" + threadName + ":进程原本不存在,不用杀进程"); + } else if (isExistFlag == 1) {// 存在且只有一个进程,杀PID + ProcessUtil.killProcess(pidInfo); + logger.info("停用" + threadName + ":杀进程 PID:" + pidInfo); + } else if (isExistFlag == 2) {// 找到多个进程,告警 + logger.info("停用" + threadName + ":" + pidInfo); +// String alarmMsg = "停用三方监测进程:" + pidInfo; + String alarmMsg = "Discontinuation Of The Three Party Monitoring Process:" + pidInfo; + AlarmUtil.sendAlarmMsg(setInfo.getId(), setInfo + .getCheckTypeName(), setInfo.getProcessIden(), + new Date(), new Date(), 1, + Contants.DETECTION_STATUS_FAILURE, alarmMsg); + } + } catch (Exception e) { + logger.error("Discontinuation of three party monitoring anomalies", e); + } + } + + /** + * 设置三方监测中由Web管理的监测脚本的启动参数(针对NC启动的周期监测)
+ * 生成三方监测的执行命令及查询关键字 + * + * @param setInfo + * @return 脚本启动命令 + */ + public static String generateCommandAndKeyword(SetInfo setInfo) { + String command = null; + try { + if ("2".equals(setInfo.getIsControlStart())) { // NC周期启动 + File scriptDir = new File(Contants.localPluginScriptPath); + final String keyword = "_" + setInfo.getProcessIden() + "."; + Collection files = FileUtils.listFiles(scriptDir, + FileFilterUtils.asFileFilter(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + if(name.endsWith(".tp")) { + return false; // 排除临时文件 + } + return name.contains(keyword); + } + }), FalseFileFilter.FALSE); + if (!files.isEmpty()) { + File scriptFile = (File) files.iterator().next(); + String os = System.getProperty("os.name"); + if (os.startsWith("Windows")) { + command = scriptFile.getCanonicalPath(); + } else if (os.startsWith("Linux")) { + command = "./ " + scriptFile.getCanonicalFile(); + } + setInfo.setProcessPath(command); // 设置执行命令 + setInfo.setProcessSearchKeyCode(scriptFile.getName()); // 搜索关键字 + // 更新缓存中的监测设置 + Common.putPluginDetecSetInfo(setInfo.getId(), setInfo); + } + } + } catch (IOException e) { + e.printStackTrace(); + } + return command; + } + + public static int byteArrayToInt(byte[] b) { + return b[3] & 0xFF | + (b[2] & 0xFF) << 8 | + (b[1] & 0xFF) << 16 | + (b[0] & 0xFF) << 24; + } + + public static byte[] intToByteArray(int a) { + return new byte[] { + (byte) ((a >> 24) & 0xFF), + (byte) ((a >> 16) & 0xFF), + (byte) ((a >> 8) & 0xFF), + (byte) (a & 0xFF) + }; + } +} diff --git a/src/com/nis/nmsclient/common/Contants.java b/src/com/nis/nmsclient/common/Contants.java new file mode 100644 index 0000000..3f43a06 --- /dev/null +++ b/src/com/nis/nmsclient/common/Contants.java @@ -0,0 +1,307 @@ +package com.nis.nmsclient.common; + +import java.io.File; + +import org.apache.commons.lang.StringUtils; + +import com.nis.nmsclient.util.FileUtil; + + +public class Contants { + + public static final String SYSTEM_PATH; //NMSClient应用启动主目录 + + /** ========= SSLSocket相关配置参数,客户与服务两端交互数据信息 ========**/ + public static final String SOCKET_SERVER_HOST_KEY= "server_host"; + public static String SOCKET_SERVER_HOST;//服务器IP + public static final Integer SOCKET_SERVER_PORT;//服务器端口 + public static final Integer SOCKET_AGENT_PORT;//客户端端口 + public static final Integer SOCKET_TIMEOUT_MINUTES;// Socket通信超时时间 + public static final String SSL_KEY_STORE;//key证书库文件 + public static final String SSL_TRUST_KEY_STORE;//认证证书库文件 + public static final String SSL_JSSE_TYPE = "TLS";//类型TLS、SSL + public static final String SSL_KEYSTORE_TYPE = "JCEKS";//KeyStore的类型有:jceks、jks + public static final String SSL_KEY_PRIVATE_PASS = "123456"; + public static final String SSL_KEY_STORE_PASS = "client"; + + public static final String keyPath; + + /**=======================本地文件相关参数========================*/ + public static final String localDetecConfSuffix;// 监测设置信息文件名后缀 + public static final String localDetecConfPath;// 监测设置信息存放路径 + public static final String localDataCollection;// 监测数据存放集 + public static final String localDataFilePath;//------------监测数据存放路径 + public static final String localDataDonePath;//------------成功处理数据存放路径 + public static final String localDataErrorPath;//------------不完整数据0大小文件存放路径 + public static final String localBackupPath;// 备份文件存放目录 + public static final String localUploadsPath;// 推送文件存入目录 + public static final String localTaskPath;// 任务相关信息存放目录 + public static final String localTaskDonePath;// ------------成功处理任务存放目录 + public static final String localTaskErrorPath;// -----------不完整0大小回传文件存放目录 + public static final String localTaskResultPath;// ------------任务结果存放目录 + public static final String localTaskReturnPath;// ------------任务回传文件存放目录 + public static final String localLogsPath;// 日志存放路径 + public static final String localTempPath;// 临时文件存放目录 + public static final String localTempDataIncomingPath; // 第三方监测临时文件存放目录 + public static final String localAgentPidFile;// Agent自身进程PID存放文件 + public static final String localPluginScriptPath;// 第三方监测脚本存放目录 + public static final String LOCAL_SCRIPT_PATH; + + /**=======================系统预计监测类型========================*/ + public static final String SYS_CHECK_TYPE_CPU; + public static final String SYS_CHECK_TYPE_MEMORY; + public static final String SYS_CHECK_TYPE_DISK; + public static final String SYS_CHECK_TYPE_NET; + public static final String SYS_CHECK_TYPE_SYSDATE; + public static final String SYS_CHECK_TYPE_PROCESS; + public static final String SYS_CHECK_TYPE_PROCESS_NMSAGENT; + public static final String SYS_CHECK_TYPE_SYSTEMINFO; + + /** =====================Common时间时隔==================== **/ + // ------------ 清除本地文件 + public static final Integer COMMON_DEL_LOG_DAYS;// 删除日志文件间隔时间 + public static final Integer COMMON_DEL_DATA_HOURS;// 删除数据文件间隔时间 + public static final Integer COMMON_DEL_TASK_HOURS;// 删除任务相关文件间隔时间 + public static final Integer COMMON_DEL_UPGRADEFILE_DAYS;// 删除升级文件间隔时间 + public static final Integer COMMON_DEL_TEMP_DAYS;// 删除临时文件间隔时间 + public static String[] COMMON_DEL_PATH_INCLUDE;// 指定Agent可删除文件的范围 + public static String[] COMMON_DEL_PATH_EXCLUDE;// 指定Agent可删除文件范围内不可删除部分 + // ------------ 监测、任务、预警 + public static final Integer COMMON_ALARM_MINUTES = 5;// 主动告警轮循间隔时间 + public static final Integer COMMON_TASK_RESULT_SEND_MINUTES = 5;// 重发之前发送失败的任务执行结果间隔时间 + public static final Integer COMMON_TASK_INIT_DELAY_MINUTES = 2;// 启动时初始化任务请求延迟时间 + public static final Integer COMMON_UPLOAD_DATA_MINUTES;// 上传数据轮循间隔时间 + public static final Integer COMMON_TASK_CLEAR_HOURS;// 定时清理内存中已完成任务的间隔时间 + // ------------线程池 + public static final Integer COMMON_THREAD_SOCKET_SIZE ;// socket通信线程最大个数 + public static final Integer COMMON_THREAD_SCHEDULE_SIZE;// 定时任务线程最大个数 + // ------------打包上传 + public static final Integer COMMON_ZIP_MIN_SIZE;// 文件数越过一定值时压缩用 + public static final Integer COMMON_ZIP_MAX_SIZE;// 文件数越过一定值时压缩文件最多包含文件个数 + public static final Integer COMMON_MAX_RETURN_CNT;// 回传文件数越过一定值时压缩用 + // -----------任务结果、主动告警等信息中各字段的分隔符 + public static final String COMMON_MSG_SEPRATOR = "$@$"; + public static final String COMMON_MSG_SEPRATOR_SPLIT = "\\$@\\$"; + public static final int COMMON_MSG_SUCCESS = 0; + public static final int COMMON_MSG_FAIL = 1; + // -----------设置文件编码方式 + public static final String charset; + + /** ========================告警状态常量========================== **/ + //用于报警: -1监测执行失败,0监测信息不正常,1监测信息正常,-2异常主动告警,2主动告警恢复正常) + public static final int DETECTION_STATUS_FAILURE = -1;//监测执行失败 + public static final int DETECTION_STATUS_ABNORMAL = 0;//监测信息不正常 + public static final int DETECTION_STATUS_NORMAL = 1;//监测信息正常 + //public static final int DETECTION_ALARM_ABNORMAL = -2;//告警检查:监测线程异常(未取到数据,相应的文件找不到,或者连续N次都超过设置的告警值) + //public static final int DETECTION_ALARM_NORMAL = 2;//告警检查:监测线程恢复正常 + + /** ========================任务部分文件后缀============================ **/ + public static final String TASK_RESULT_FILE_SUFFIX = ".result"; + public static final String TASK_RESULT_AGENTTMPFILE_SUFFIX = ".upgrade"; + public static final String TASK_RETURN_FILE_SUFFIX = ".return"; + + /** ========================Debug============================ **/ + public static final Integer DEBUG_INIT_TASK_FLAG; + public static final Integer DEBUG_PLUGIN_FLAG; + public static final Integer DEBUG_SYSDETECT_FLAG; + public static final Integer DEBUG_UPLOADDATA_FLAG; + public static final Integer DEBUG_ALARM_FLAG; + public static final Integer DEBUG_DELFILE_FLAG; + public static final Integer DEBUG_TASKRESULT_FLAG; + public static final Integer DEBUG_TASKRETURN_FLAG; + + //================= + public static final int max_times = 5;// 失败后重试次数 + public static final long max_delay_seconds = 30;// 重试间隔,秒 + public static final int noDataTimes = 4;// 未取到数据的次数,用于主动告警 + public static final int overAlarmValTimes = 4;// 连续超过预警值的次数,用于主动告警 + //--------------Agent唯一标志UUID + public static Long AGENT_HOST_UUID = null; + public static String AGENT_OPERATE_SYSTEM = null; + public static String AGENT_LOCAL_IP = null; + + public static final String DETEC_STATE_INFO_FORMATE_POINT = "$@$";//用于监测数据的状态信息web界面显示的格式化的连接符 + + public static Boolean ACTIIVE_ALARM_START = false;//默认不启动主动告警 + public static String AGENT_INTERFACE_NAME_KEY = null;//网络端口名称 + /** + * 监测数据主动上报 + */ + //监测数据主动上报 + public static final int DATA_SEND_THREAD_FLAG; + //主动数据上报 IP + public static final String DATA_SEND_THREAD_HOST; + //主动数据上报 PORT + public static final int DATA_SEND_THREAD_PORT; + //主动数据上报间隔 INTERVAL,单位 10 S + public static final int DATA_SEND_THREAD_INTERVAL; + + static{ + SYSTEM_PATH = SysConfig.getSystemDir(); + + // -------------------SSLSocket + SOCKET_SERVER_HOST = SysConfig.getStringVal(SOCKET_SERVER_HOST_KEY); + SOCKET_SERVER_PORT = SysConfig.getIntegerVal("server_port"); + SOCKET_AGENT_PORT = SysConfig.getIntegerVal("agent_port"); + SOCKET_TIMEOUT_MINUTES = SysConfig.getIntegerVal("socket.timeout.minutes", "30"); + SSL_KEY_STORE = formatPath(SysConfig.getStringVal("local.ssl.keys")); + SSL_TRUST_KEY_STORE = formatPath(SysConfig.getStringVal("local.ssl.trust")); + + keyPath = formatPath(SysConfig.getStringVal("local.ssl.path")); + + /*=======================文件相关参数========================*/ + // 可删范围 + String path = SysConfig.getStringVal("common.del.path.include"); + if(path!=null && !"".equals(path)){ + COMMON_DEL_PATH_INCLUDE = path.split(","); + for(int i=0; i 24){ + COMMON_DEL_TASK_HOURS = COMMON_DEL_DATA_HOURS; + }else{ + COMMON_DEL_TASK_HOURS = 24; + } + COMMON_DEL_UPGRADEFILE_DAYS = SysConfig.getIntegerVal("common.del.upgradefile.days", "30"); + COMMON_DEL_TEMP_DAYS = SysConfig.getIntegerVal("common.del.temp.days", "2"); + COMMON_UPLOAD_DATA_MINUTES = SysConfig.getIntegerVal("common.upload.data.minutes", "5"); + COMMON_TASK_CLEAR_HOURS = SysConfig.getIntegerVal("common.task.clear.hours", "2"); + + // -------------- ThreadPool + COMMON_THREAD_SOCKET_SIZE = SysConfig.getIntegerVal("common.thread.socket.size", "10"); + COMMON_THREAD_SCHEDULE_SIZE = SysConfig.getIntegerVal("common.thread.schedule.size", "15"); + // -------------- Compress + COMMON_ZIP_MIN_SIZE = SysConfig.getIntegerVal("common.zip.min.size", "1000"); + COMMON_ZIP_MAX_SIZE = SysConfig.getIntegerVal("common.zip.max.size", "2000"); + COMMON_MAX_RETURN_CNT = SysConfig.getIntegerVal("common.max.return.size", "10"); + // ----------------Debug + DEBUG_INIT_TASK_FLAG = SysConfig.getIntegerVal("debug.init.task.flag", "0"); + DEBUG_PLUGIN_FLAG = SysConfig.getIntegerVal("debug.plugin.flag", "0"); + DEBUG_SYSDETECT_FLAG = SysConfig.getIntegerVal("debug.sysdetect.flag", "0"); + DEBUG_UPLOADDATA_FLAG = SysConfig.getIntegerVal("debug.uploaddata.flag", "0"); + DEBUG_ALARM_FLAG = SysConfig.getIntegerVal("debug.alarm.flag", "0"); + DEBUG_DELFILE_FLAG = SysConfig.getIntegerVal("debug.delfile.flag", "0"); + DEBUG_TASKRESULT_FLAG = SysConfig.getIntegerVal("debug.taskresult.flag", "0"); + DEBUG_TASKRETURN_FLAG = SysConfig.getIntegerVal("debug.taskreturn.flag", "0"); + +// ACTIIVE_ALARM_START = SysConfig.getStringVal("active.alarm.start", "true");//是否启用主动告警,默认不启动主动告警---用于nc配置文件,现修改为从web控制 + + + //监测数据主动上报 + DATA_SEND_THREAD_FLAG = SysConfig.getIntegerVal("data.send.thread.flag", "0"); + //主动数据上报 IP + DATA_SEND_THREAD_HOST = SysConfig.getStringVal("data.send.thread.host", SOCKET_SERVER_HOST); + //主动数据上报 PORT + DATA_SEND_THREAD_PORT = SysConfig.getIntegerVal("data.send.thread.port", "9527"); + //主动数据上报间隔 INTERVAL,单位 10 S + DATA_SEND_THREAD_INTERVAL = SysConfig.getIntegerVal("data.send.thread.interval", "10"); + + + // 初始化创建文件夹 + if(!new File(localDetecConfPath).exists()){ + new File(localDetecConfPath).mkdirs(); + } + if(!new File(localPluginScriptPath).exists()) { + new File(localPluginScriptPath).mkdirs(); + } + if(!new File(localDataCollection).exists()){ + new File(localDataCollection).mkdirs(); + } + if(!new File(localBackupPath).exists()){ + new File(localBackupPath).mkdirs(); + } + if(!new File(localUploadsPath).exists()){ + new File(localUploadsPath).mkdirs(); + } + if(!new File(localTaskPath).exists()){ + new File(localTaskPath).mkdirs(); + } + if(!new File(localTempPath).exists()){ + new File(localTempPath).mkdirs(); + } + if(!new File(localTempDataIncomingPath).exists()){ + new File(localTempDataIncomingPath).mkdirs(); + } + } + + private static String formatPath(String path){ + String returnPath = path; + if(path!=null && !"".equals(path) && !new File(path).isAbsolute()){// 路径不为空且是相对路径 + returnPath = SYSTEM_PATH + File.separator + path; + } + return returnPath; + } + + public static boolean isSucessByResult(String msg){ + boolean flag = false; + if (!StringUtils.isEmpty(msg)) { + String[] result = msg.split(Contants.COMMON_MSG_SEPRATOR_SPLIT); + if (result != null && result.length > 0) { + if (Integer.parseInt(result[0])==Contants.COMMON_MSG_SUCCESS) { + flag = true; + } + } + } + return flag; + } + + public static String getDescByResult(String msg){ + String desc = null; + if (!StringUtils.isEmpty(msg)) { + String[] result = msg.split(Contants.COMMON_MSG_SEPRATOR_SPLIT); + if (result != null && result.length > 1) { + desc = result[1]; + } + } + return desc; + } +} diff --git a/src/com/nis/nmsclient/common/StopWatch.java b/src/com/nis/nmsclient/common/StopWatch.java new file mode 100644 index 0000000..f11655f --- /dev/null +++ b/src/com/nis/nmsclient/common/StopWatch.java @@ -0,0 +1,152 @@ +package com.nis.nmsclient.common; + +import java.util.LinkedHashMap; + +/** + * 秒表计时器 + * @author fang + * + */ +public class StopWatch { + private static final long SEC_MILL = 1000; + private static final long MIN_MILL = 60 * SEC_MILL; + private static final long HOUR_MILL = 60 * MIN_MILL; + private static final long DAY_MILL = 24 * HOUR_MILL; + private long start; + private long end; + private LinkedHashMap tagMap = new LinkedHashMap(); + + public StopWatch(){ + start(); + } + + public static StopWatch newStopWacth(){ + return new StopWatch(); + } + + /** + * 计时器开始 + * @return + */ + public long start(){ + this.start = System.currentTimeMillis(); + return start; + } + + /** + * 计时器结束 + * @return + */ + public long end(){ + this.end = System.currentTimeMillis(); + return end; + } + + + public long tag(String tag){ + long l = System.currentTimeMillis(); + this.tagMap.put(tag, l); + return l; + } + + /** + * 计算两个 tag 之间的时间差 + * @param b + * @param a + * @return + */ + public long between(String b,String a){ + Long l1 = this.tagMap.get(b); + Long l2 = this.tagMap.get(a); + if(l1 != null && l2 != null){ + return l1-l2; + } + return -1; + } + + public static String toString(long l){ + StringBuilder sb = new StringBuilder(); + if(l >= DAY_MILL){ + sb.append((l/DAY_MILL)); + sb.append( "天"); + l = l % DAY_MILL; + } + if(l >= HOUR_MILL){ + sb.append((l/HOUR_MILL)); + sb.append( "小时"); + l = l % HOUR_MILL; + } + if(l >= MIN_MILL){ + sb.append((l/MIN_MILL)); + sb.append( "分"); + l = l % MIN_MILL; + } + if(l >= SEC_MILL){ + sb.append((l/SEC_MILL)); + sb.append( "秒"); + l = l % SEC_MILL; + } + + sb.append((l)); + sb.append( "毫秒"); + + return sb.toString(); + } + + public String toString(){ + + return ""; + } + + /** + * 从开始到结束总耗时 + * @return + */ + public long total(){ + long temp = System.currentTimeMillis(); + if(this.end < this.start){ + this.end = temp; + } + return end - start; + } + + + public void reset(){ + this.tagMap.clear(); + this.start(); + } + + public long getStart() { + return start; + } + + public void setStart(long start) { + this.start = start; + } + + public long getEnd() { + return end; + } + + public void setEnd(long end) { + this.end = end; + } + + public LinkedHashMap getTag() { + return tagMap; + } + + public void LinkedHashMap(LinkedHashMap tag) { + this.tagMap = tag; + } + + public static void main(String[] args) { + long s = System.currentTimeMillis(); + long end = s +2*DAY_MILL+ 12 * MIN_MILL + 30*SEC_MILL + 388; + + String string = StopWatch.toString(end -s); + System.out.println(string); + + } + +} diff --git a/src/com/nis/nmsclient/common/SysConfig.java b/src/com/nis/nmsclient/common/SysConfig.java new file mode 100644 index 0000000..e22a35f --- /dev/null +++ b/src/com/nis/nmsclient/common/SysConfig.java @@ -0,0 +1,365 @@ +package com.nis.nmsclient.common; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.net.URL; +import java.nio.charset.Charset; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Properties; +import java.util.ResourceBundle; + +import javax.swing.JOptionPane; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + + +public class SysConfig { + static Logger logger = Logger.getLogger(SysConfig.class); + + /** ==============myconfig.properties文件获取参数=============== **/ + private static Properties myProperties; + private static String url = null; + static { + URL urlObj = SysConfig.class.getClassLoader().getResource("myconfig.properties"); + if(urlObj==null){ +// JOptionPane.showMessageDialog(null, "缺少配置文件,程序无法执行!\n请先执行参数配置程序进行配置", "错误", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(null, "i18n_client.Sysconfig.init_n81i", "i18n_client.Sysconfig.error_n81i", JOptionPane.ERROR_MESSAGE); + logger.error("NMSClient program termination: lack of configuration files, programs can not be executed! Please execute the configuration program for configuration first"); + System.exit(0); + }else{ + url = urlObj.getPath().replaceAll("%20", " "); + } + myProperties = new Properties(); + + FileInputStream fis = null; + try { + fis = new FileInputStream(url); + myProperties.load(fis); + } catch (IOException e) { + logger.error("Reading myconfig.properties file error", e); + }finally{ + try { + if(fis!= null)fis.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + // 升级时更新参数配置使用 + updateConfigFile(); + } + + /** + * 向资源配置文件host_uuid.properties中更新UUID键值 + */ + public static void setInterfaceNameValue(String value) { + try { + Properties properties = new Properties(); + if (uuidUrl != null && !"".equals(uuidUrl)) { + properties.load(new FileInputStream(uuidUrl)); + // 添加或更新键值对 + properties.setProperty(AGENT_INTERFACE_NAME_KEY, value); + // 保存到文件 + properties.store(new FileOutputStream(uuidUrl), ""); + } + properties.clear(); + + if(value != null && !"".equals(value)){ + Contants.AGENT_INTERFACE_NAME_KEY = value; + } + } catch (Exception e) { + logger.error("Setting the network port name eth* attribute error", e); + } + } + + + /** + * 根据相应的参数配置来更新配置并写入文件 + */ + private static void updateConfigFile(){ + FileInputStream fis = null; + BufferedReader reader = null; + BufferedWriter writer = null; + try { + ResourceBundle resource = ResourceBundle.getBundle(UpdateParams.class.getName()); + //判断是否更新properties + String updateFlag = myProperties.getProperty(UpdateParams.CONFIG_UPDATE_FLAG,"-1"); + if(updateFlag.equals(resource.getString(UpdateParams.CONFIG_UPDATE_FLAG))){ //配置文件已经更新,退出操作 + return; + } + + List proList = new LinkedList(); + + String encode = System.getProperty("file.encoding"); + logger.debug("----file.encoding----" + encode); + + //读取配置文件原有的参数到proList + fis = new FileInputStream(url); + reader = new BufferedReader(new InputStreamReader(fis,Charset.forName(encode))); + String str =null; + while((str = reader.readLine() )!=null){ + proList.add(str); + } + + //将UpdateParams中的值更新到proList和myProperties中 + Enumeration en = resource.getKeys(); + while (en.hasMoreElements()) { + String elem = (String) en.nextElement(); + String value = resource.getString(elem); + boolean addFlag = true; + try { + for (int i = 0; i < proList.size(); i++) { + String strV = proList.get(i); + if (StringUtils.isEmpty(strV)) { + continue; + } + if(strV.split("=", 2)[0].trim().equals(elem)){ + if(elem.equalsIgnoreCase(UpdateParams.CONFIG_UPDATE_FLAG)){ + proList.set(i, elem + " = " + value);// 更新配置文件中某属性的值 + logger.info("参数更新:" + elem + " = " + (StringUtils.isBlank(value) ? "" : value)); + myProperties.put(elem, value); + } + addFlag = false; + break ; + } + } + + if(addFlag){ + proList.add(elem + " = " + value); + logger.info("参数新增:" + elem + " = " + (StringUtils.isBlank(value) ? "" : value)); + myProperties.put(elem, value); + } + } catch (Exception e) { + logger.error("Update the configuration file myconfig.properties parameter " + elem + "error", e); + } + } + + //将文件信息写入到文件中 + writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(url),Charset.forName(encode))); + Iterator it = proList.iterator(); + while (it.hasNext()) { + String elem = (String) it.next(); + writer.write((elem==null?"":elem)+"\r\n"); + } + writer.flush(); + + } catch (Exception e) { + logger.error("Update configuration file myconfig.properties exception", e); + } finally{ + try { + if(reader!= null)reader.close(); + if(fis!= null)fis.close(); + if(writer!= null ){ + writer.close(); + writer = null; + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + public static void updateConfigFile(String key, String value){ + FileInputStream fis = null; + BufferedReader reader = null; + BufferedWriter writer = null; + try { + List proList = new LinkedList(); + + String encode = System.getProperty("file.encoding"); + logger.debug("----file.encoding----" + encode); + + //读取配置文件原有的参数到proList + fis = new FileInputStream(url); + reader = new BufferedReader(new InputStreamReader(fis,Charset.forName(encode))); + String str =null; + while((str = reader.readLine() )!=null){ + proList.add(str); + } + + //将值更新到proList中 + try { + for (int i = 0; i < proList.size(); i++) { + String strV = proList.get(i); + if (StringUtils.isEmpty(strV)) { + continue; + } + if(strV.split("=", 2)[0].trim().equals(key)){ + proList.set(i, key + " = " + value);// 更新配置文件中某属性的值 + logger.info("参数更新:" + key + " = " + (StringUtils.isBlank(value) ? "" : value)); + break ; + } + } + } catch (Exception e) { + logger.error("Update the configuration file myconfig.properties parameter " + key + "error", e); + } + + //将文件信息写入到文件中 + writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(url),Charset.forName(encode))); + Iterator it = proList.iterator(); + while (it.hasNext()) { + String elem = (String) it.next(); + writer.write((elem==null?"":elem)+"\r\n"); + } + writer.flush(); + + } catch (Exception e) { + logger.error("Update configuration file myconfig.properties exception", e); + } finally{ + try { + if(reader!= null)reader.close(); + if(fis!= null)fis.close(); + if(writer!= null ){ + writer.close(); + writer = null; + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + public static String getStringVal(String key, String... defaultVal){ + String dStr = ""; + if(defaultVal!=null && defaultVal.length>=1 && defaultVal[0]!=null && defaultVal.length>0){ + dStr = defaultVal[0]; + } + return myProperties.getProperty(key,dStr).trim(); + } + + public static Integer getIntegerVal(String name, String... defaultVal){ + try { + String val = getStringVal(name, defaultVal); + return StringUtils.isEmpty(val)? null : Integer.parseInt(val); + } catch (Exception e) { + logger.error("Digital formatting error", e); + } + return null; + } + + public static String getSystemDir() { + return System.getProperty("user.dir"); + } + + public static String getLogPath(){ + FileInputStream fis = null; + try { + String log4jUrl = SysConfig.class.getClassLoader().getResource("log4j.properties").getPath().replaceAll("%20", " "); + fis = new FileInputStream(log4jUrl); + Properties log4jProperties = new Properties(); + log4jProperties.load(fis); + String logFile = log4jProperties.getProperty("log4j.appender.logfile.File"); + if(logFile!=null){ + return new File(logFile).getParent(); + } + } catch (IOException e) { + logger.error("Reading log4j.properties file error"+"",e); + }finally{ + try { + if(fis!= null)fis.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + return "../logs"; + } + + /** ==============host_uuid.properties文件获取参数=============== **/ + static final String AGENT_HOST_UUID_KEY = "agent_host_uuid"; + static final String AGENT_OPERATE_SYSTEM_KEY = "agent_operate_system"; + static final String AGENT_LOCAL_IP_KEY = "agent_local_ip"; + static String uuidUrl = null; + static final String AGENT_INTERFACE_NAME_KEY = "agent_interface_name"; + static { + String name = "host_uuid.properties"; + // 2014-11-13 jzz modify 由于将该配置文件放于系统安装目录中容易使节点混乱,故将其放于nmsdata指定目录 + /*URL urlObj = Contants.class.getClassLoader().getResource(name); + if(urlObj==null){ + uuidUrl = new File(url).getParent() + File.separator + name; + }else{ + uuidUrl = urlObj.getPath().replaceAll("%20", " "); + }*/ + String path = SysConfig.getStringVal("local.data.path") + File.separator + "nc_sysconf"; + File filePath = new File(path); + if(!filePath.exists()){ + filePath.mkdirs(); + } + + uuidUrl = path + File.separator + name; + + Properties properties = new Properties(); + try { + File file = new File(uuidUrl); + if(!file.exists()){ + file.createNewFile(); + } + properties.load(new FileInputStream(uuidUrl)); + String uuidStr = properties.getProperty(AGENT_HOST_UUID_KEY); + if(uuidStr != null && !"".equals(uuidStr.trim())){ + Contants.AGENT_HOST_UUID = Long.parseLong(uuidStr.trim()); + } + Contants.AGENT_OPERATE_SYSTEM = properties.getProperty(AGENT_OPERATE_SYSTEM_KEY); + Contants.AGENT_LOCAL_IP = properties.getProperty(AGENT_LOCAL_IP_KEY); + Contants.AGENT_INTERFACE_NAME_KEY = properties.getProperty(AGENT_INTERFACE_NAME_KEY); + } catch (IOException e) { + logger.error("Reading host_uuid.properties file error", e); + } + properties.clear(); + } + + /** + * 向资源配置文件host_uuid.properties中更新UUID键值 + */ + public static void setUUIDValue(String value) { + try { + Properties properties = new Properties(); + if (uuidUrl != null && !"".equals(uuidUrl)) { + properties.load(new FileInputStream(uuidUrl)); + // 添加或更新键值对 + properties.setProperty(AGENT_HOST_UUID_KEY, value); + // 保存到文件 + properties.store(new FileOutputStream(uuidUrl), ""); + } + properties.clear(); + + if(value != null && !"".equals(value)){ + Contants.AGENT_HOST_UUID = Long.parseLong(value); + } + } catch (Exception e) { + logger.error("Setting the UUID attribute error", e); + } + } + + /** + * 向资源配置文件host_uuid.properties中更新OperateSystem和LocalIP键值 + */ + public static void setUUIDValue(String sysTypeValue,String localIpValue) { + try { + Properties properties = new Properties(); + if (uuidUrl != null && !"".equals(uuidUrl)) { + properties.load(new FileInputStream(uuidUrl)); + // 添加或更新键值对 + properties.setProperty(AGENT_OPERATE_SYSTEM_KEY, sysTypeValue); + properties.setProperty(AGENT_LOCAL_IP_KEY, localIpValue); + // 保存到文件 + properties.store(new FileOutputStream(uuidUrl), ""); + } + properties.clear(); + Contants.AGENT_OPERATE_SYSTEM = sysTypeValue; + Contants.AGENT_LOCAL_IP = localIpValue; + } catch (Exception e) { + logger.error("Setting OperateSystemType and LocalIP attribute errors",e); + } + } +} diff --git a/src/com/nis/nmsclient/common/UpdateParams.java b/src/com/nis/nmsclient/common/UpdateParams.java new file mode 100644 index 0000000..b79b9fc --- /dev/null +++ b/src/com/nis/nmsclient/common/UpdateParams.java @@ -0,0 +1,18 @@ +package com.nis.nmsclient.common; + +public class UpdateParams extends java.util.ListResourceBundle { + public static String CONFIG_UPDATE_FLAG = "config.update.flag"; //更新标示 固定 判断配置文件指定值更新 建议自增1操作 + public static String CONFIG_UPDATE_FLAG_VALUE = "5"; //更新标示 该值 缺省值为0 每次修改都要 + static final String[][] contents = new String[][]{ + {CONFIG_UPDATE_FLAG,CONFIG_UPDATE_FLAG_VALUE}, //更新标示 固定 判断配置文件指定值更新 建议自增1操作 + {"socket.timeout.minutes", "30"}, // Socket通信超时时间设置 + {"common.zip.min.size", "1000"}, // 压缩文件最少包含文件个数 + {"common.zip.max.size", "2000"}, // 压缩文件最多包含文件个数 +// {"active.alarm.start","false"}, //是否启用NC的主动告警(只针对监测数据超过设置的值时的主动告警,避免异常信息重复):true:启用,false:停用-暂不使用,修改为web端控制nc是否报主动告警 + {"alarm.set.marker.separator","|"} //监测数据设置告警时,对于指定多个标识符(如多个盘符、多个CPU、多个网卡)的分隔符 + }; + + public Object[][] getContents() { + return contents; + } +} diff --git a/src/com/nis/nmsclient/common/VersionCfg.java b/src/com/nis/nmsclient/common/VersionCfg.java new file mode 100644 index 0000000..f48812c --- /dev/null +++ b/src/com/nis/nmsclient/common/VersionCfg.java @@ -0,0 +1,75 @@ +package com.nis.nmsclient.common; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Properties; + +import org.apache.log4j.Logger; + +/** + * 获取和保存version信息的类 + * + */ +public class VersionCfg { + private static Logger logger = Logger.getLogger(VersionCfg.class); + public static final String NAGENT_VERSION = "NA_version"; + public static final String NSERVER_VERSION = "NS_version"; + + private static String url = null; + private static Properties properties; + + static { + url = VersionCfg.class.getClassLoader().getResource("version.properties").getPath().replaceAll("%20", " "); + + FileInputStream fis = null; + properties = new Properties(); + try { + fis = new FileInputStream(url); + properties.load(fis); + } catch (IOException e) { + logger.error("Reading version.properties file error", e); + }finally{ + try{ + if(fis!=null){ + fis.close(); + } + }catch (Exception e) {} + } + } + + /** + * 获取version值 + * + */ + public static String getValue(String key) { + return properties.getProperty(key); + } + + /** + * 向资源配置文件中添加或更新version键值对 + */ + public static void setValue(String key, String value) { + logger.debug("setVersion----->" + key + "=" + value); + // 添加或更新键值对 + properties.setProperty(key, value); + logger.debug("properties.getProperty(\"" + key + "\")----->" + value); + FileOutputStream fos = null; + try { + fos = new FileOutputStream(url); + // 保存到文件 + if (url != null && !"".equals(url)) { + properties.store(fos, ""); + } + } catch (Exception e) { + logger.error(e); + } finally{ + try{ + if(fos!=null){ + fos.flush(); + fos.close(); + } + }catch (Exception e) {} + } + } +} diff --git a/src/com/nis/nmsclient/config/DetecConfOper.java b/src/com/nis/nmsclient/config/DetecConfOper.java new file mode 100644 index 0000000..a3fc65b --- /dev/null +++ b/src/com/nis/nmsclient/config/DetecConfOper.java @@ -0,0 +1,58 @@ +package com.nis.nmsclient.config; + +import java.io.File; + +import org.apache.log4j.Logger; + +import com.nis.nmsclient.common.Contants; +import com.nis.nmsclient.model.SetInfo; + +public class DetecConfOper { + static Logger logger = Logger.getLogger(DetecConfOper.class); + + public static File getConfigFile(File dir, String fileName) { + File tmp = null; + if (dir.isDirectory()) { + for (File f : dir.listFiles()) { + if (!f.isDirectory()) { + if (f.getName().equals(fileName)) { + tmp = f; + break; + } + } + } + } + return tmp; + } + + public static String getFileName(String checkType, String processIden, + String suffix) { + String fileName = ""; + if (checkType != null && !"".equals(checkType)) { + fileName += checkType; + } + if (processIden != null && !"".equals(processIden)) { + fileName += "_" + processIden; + } + if (suffix != null && !"".equals(suffix)) { + fileName += suffix; + } + + return fileName; + } + + public static boolean isProcess(SetInfo setInfo){ + boolean flag = false; + if("1".equals(setInfo.getIsSchedule())){//非预设监测 + flag = true; + }else if(Contants.SYS_CHECK_TYPE_PROCESS.equalsIgnoreCase(setInfo.getCheckTypeName())){ + flag = true; + } + return flag; + } + + public static String getProcess(SetInfo setInfo){ + return setInfo.getProcessPath();// + File.separator + setInfo.getProcessFile(); + } + +} diff --git a/src/com/nis/nmsclient/config/DetecConfReqHandle.java b/src/com/nis/nmsclient/config/DetecConfReqHandle.java new file mode 100644 index 0000000..22ef967 --- /dev/null +++ b/src/com/nis/nmsclient/config/DetecConfReqHandle.java @@ -0,0 +1,297 @@ +package com.nis.nmsclient.config; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import net.sf.json.JSONArray; +import net.sf.json.JSONObject; + +import org.apache.log4j.Logger; + +import com.nis.nmsclient.common.Common; +import com.nis.nmsclient.common.Contants; +import com.nis.nmsclient.model.AlarmInfo; +import com.nis.nmsclient.model.SetInfo; +import com.nis.nmsclient.thread.alarm.AlarmUtil; +import com.nis.nmsclient.util.FileUtil; +import com.nis.nmsclient.util.FileWrUtil; +import com.nis.nmsclient.util.ProcessUtil; +import com.nis.nmsclient.util.Utils; + +public class DetecConfReqHandle { + Logger logger = Logger.getLogger(DetecConfReqHandle.class); + + /** + * 初始化监测配置 + * 处理接收到监测配置信息:解析成自定义的对象 + * @param str JSONObject串 + */ + public void handlerConfigByInit(String str, List setInfos, Map> alarmInfos) { + // -- 参数处理 + if (str == null || str.trim().length() <= 0) { + return; + } + if(setInfos==null || alarmInfos == null){ + return; + } + setInfos.clear(); + alarmInfos.clear(); + + // -- 初始化配置环境处理 + File file = new File(Contants.localDetecConfPath); + if (!file.exists()) {// 判断存放目录是否存在,不存创建 + file.mkdirs(); + } + File[] cfgFiles = file.listFiles(); + for (int i = 0; i < cfgFiles.length; i++) {//清空所有配置文件 + // 使用删除文件公共方法 + FileUtil.delDir(cfgFiles[i]); + logger.debug("handlerConfigByInit()--delete file=" + cfgFiles[i].getAbsolutePath()); + } + + // -- 监测配置解析 + JSONObject jsonObj = JSONObject.fromObject(str); + + List setList = null; + if (str.toLowerCase().contains("setinfo")) { + JSONArray jsonArr = jsonObj.getJSONArray("setInfo"); + setList = handerSetInfo(jsonArr); + } + if (setList == null || setList.size() == 0) { + return; + } + Map> alarmMap = null; + if (str.toLowerCase().contains("alarminfo")) { + JSONArray jsonArr = jsonObj.getJSONArray("alarmInfo"); + alarmMap = handerAlarmInfo(jsonArr, setList); + } + // 20170413 zbc 缓存AlarmInfo信息(cfg文件中无报警单位字段) + if(alarmMap != null) { + Common.putAllDetecAlarmInfo(alarmMap); + } + + for (SetInfo setInfo : setList) { + if ("1".equals(setInfo.getCheckState()) + && "1".equals(setInfo.getCheckWay())) {// 有效,被动方式获取 + setInfos.add(setInfo); + Common.addOrUpdateAlarmPO(AlarmUtil.getAlarmPO(setInfo)); + } + } + if (alarmMap != null && alarmMap.size()>0) { + alarmInfos.putAll(alarmMap); + } + + if (str.toLowerCase().contains("showautoalarm")) { + Object obj = jsonObj.get("showAutoAlarm"); + if (obj != null) { + Contants.ACTIIVE_ALARM_START = (Boolean) obj; + } + } + } + + /** + * 更新监测配置:先解析成自定义的对象,再根据对象信息添加、更新、停用监测 + * 注:三方监测停用时Agent根据指定的PID杀掉进程 + * @param str JSONObject串 + */ + public void handlerConfigByUpdate(String str) { + if (str == null || str.trim().length() <= 0) { + return; + } + + File file = new File(Contants.localDetecConfPath); + if (!file.exists()) {// 判断存放目录是否存在,不存创建 + file.mkdirs(); + } + + JSONObject jsonObj = JSONObject.fromObject(str); + /*long flag = -1; + if (str.toLowerCase().contains("number")) { + flag = jsonObj.getLong("number"); + }*/ + List setList = null; + if (str.toLowerCase().contains("setinfo")) { + JSONArray jsonArr = jsonObj.getJSONArray("setInfo"); + setList = handerSetInfo(jsonArr); + } + if (setList == null || setList.size() == 0) { + return; + } + Map> alarmMap = null; + if (str.toLowerCase().contains("alarminfo")) { + JSONArray jsonArr = jsonObj.getJSONArray("alarmInfo"); + alarmMap = handerAlarmInfo(jsonArr, setList); + } + + for (SetInfo setInfo : setList) { + if ("0".equals(setInfo.getCheckState()) + || "0".equals(setInfo.getCheckWay())) {// 将有效置为无效,或者将被动设为主动,停止线程 + Common.removeAlarmPO(setInfo.getId()); + if ("0".equals(setInfo.getIsSchedule())) { + Common.stopSysDetec(setInfo); + } else { + Common.stopPluginDetec(setInfo); + } + } else { + Common.addOrUpdateAlarmPO(AlarmUtil.getAlarmPO(setInfo)); + if ("0".equals(setInfo.getIsSchedule())) {// 如果是系统预设监测类型,则修改相应的监控线程 + List alarmList = null; + if (alarmMap != null) { + alarmList = alarmMap.get(setInfo.getId()); + } + Common.addOrUpdateSysDetec(setInfo, alarmList); + } else { // 第三方监测 + // 缓存三方监测配置信息,用于合并临时结果文件 + Common.putPluginDetecSetInfo(setInfo.getId(), setInfo); + + if(!Common.COMMON_SYS_SETINFO.equals(setInfo.getIsSchedule())) { // 由Agent启动的第三方插件 + Common.startPluginDetec(setInfo); + } + } + } + }// for end + } + + /** + * 解析监测设置基本信息 + * 1、相应类型的监测数据目录不存在,创建,若是Linux并赋读写权限 + * 2、监测配置文件存在,先删除再重写,停用监测不再重写 + */ + private List handerSetInfo(JSONArray jsonArr) { + // 文件路径 + List setList = new ArrayList(); + for (int i = 0; i < jsonArr.size(); i++) { + Object obj = JSONObject.toBean(JSONObject + .fromObject(jsonArr.get(i)), SetInfo.class); + if (obj == null) { + continue; + } + SetInfo setInfo = (SetInfo) obj; + // 创建建相应类型的数据文件夹 + File dataDir = new File(Contants.localDataFilePath + + File.separator + + DetecConfOper.getFileName(setInfo.getCheckTypeName(), + setInfo.getProcessIden(), null)); + if (!dataDir.exists()) { + dataDir.mkdirs(); + logger.debug("handerSetInfo()--create dataDir=" +dataDir.getAbsolutePath()); + } + // 文件名 + String fileName = DetecConfOper.getFileName( + setInfo.getCheckTypeName(), setInfo.getProcessIden(), + Contants.localDetecConfSuffix); + + // 判断文件是否存在,如果存在删除 + File cfgfile = new File(Contants.localDetecConfPath + File.separator + + fileName); + if (cfgfile.exists()){ + //cfgfile.delete_bak(); + //使用删除文件公共方法 + FileUtil.delDir(cfgfile); + logger.debug("handerSetInfo()--delete cfgfile=" + cfgfile.getAbsolutePath()); + //FileUtil.checkParentDirExist(cfgfile); + } + + if ("1".equals(setInfo.getCheckState()) + && "1".equals(setInfo.getCheckWay())) {//有效且被动方式获取的写入配置文件 + String dataDirStr = null; + try {// 为了去除路径中的"." 和 ".." + dataDirStr = dataDir.getCanonicalPath(); + } catch (IOException e) { + dataDirStr = dataDir.getAbsolutePath(); + } + try { + FileWrUtil.cfgFilePrinter(cfgfile, Contants.charset, + setInfo.getValArr(Contants.AGENT_HOST_UUID, dataDirStr)); + logger.debug("handerSetInfo()--write cfgfile=" + cfgfile.getAbsolutePath()); + } catch (Exception e) { + logger.error("Write the document“" + cfgfile.getAbsolutePath() + "”error: " + Utils.printExceptionStack(e)); + continue; + } + } + setList.add(setInfo); + + }// for end + //修改数据目录的权限 + ProcessUtil.permit(777, new File(Contants.localDataFilePath)); + + return setList; + } + + /** + * 解析监测设置的告警信息 + * 1、将同一监测的所有告警信息整理放到一个列表 + * 2、根据监测设置类型和设置名称找配置文件,找到了将告警信息追加到配置文件 + * 3、只要有监测设置,不管有没有设置告警信息,都要将相应字段追加到配置文件,只是无告警信息时,配置字段为空 + */ + private Map> handerAlarmInfo(JSONArray jsonArr, List setList) { + if(setList==null || setList.size()==0){ + logger.info("无监测设置信息,无需处理报警设置"); + return null; + } + File dir = new File(Contants.localDetecConfPath); + if (!dir.exists()) {// 判断存放目录是否存在, 不存在返回 + logger.error("Please check whether the alarm settings information is consistent with the monitoring settings information!"); + return null; + } + Map> alarmMap = new HashMap>(); + if(jsonArr!=null){ + for (int i = 0; i < jsonArr.size(); i++) { + Object obj = JSONObject.toBean(JSONObject + .fromObject(jsonArr.get(i)), AlarmInfo.class); + if (obj != null) { + AlarmInfo alarmInfo = (AlarmInfo) obj; + if (alarmMap.containsKey(alarmInfo.getSetInfoId())) {// 如果报警信息中已经存在相应类型的报警则追加 + List aList = alarmMap.get(alarmInfo.getSetInfoId()); + aList.add(alarmInfo); + alarmMap.put(alarmInfo.getSetInfoId(), aList); + } else { + List aList = new ArrayList(); + aList.add(alarmInfo); + alarmMap.put(alarmInfo.getSetInfoId(), aList); + } + } + } + } + Map> alarmMapNew = new HashMap>(); + // 依次查看监测设置信息,不管有没有设置告警信息,都要写配置police=,若无告警信息,配置字段值为空 + for(SetInfo setInfo : setList){ + Long key = setInfo.getId(); + List alarmList = alarmMap.get(key); + // 配置信息保存对应的文件名 + String fileName = DetecConfOper.getFileName( + setInfo.getCheckTypeName(), setInfo.getProcessIden(), + Contants.localDetecConfSuffix); + File f = DetecConfOper.getConfigFile(dir, fileName); + {// 追加报警设置到相应的监测配置文件 + if (f != null && f.exists()) + try { + FileWrUtil.cfgFileAppender(f, + Contants.charset, new String[]{getAlarmArr(alarmList)}); + if(alarmList!=null){// 只有成功保存了文件并且设置为告警信息的,才返回给上一方法 + alarmMapNew.put(key, alarmList); + } + } catch (Exception e) { + logger.error("Write the document“" + f.getAbsolutePath() + "”error: " + Utils.printExceptionStack(e)); + } + } + } + return alarmMapNew; + } + + private static String getAlarmArr(List alarmList) { + StringBuffer sb = new StringBuffer(); + sb.append("police="); + if (alarmList != null && alarmList.size() > 0) { + for (AlarmInfo alarmInfo : alarmList) { + sb.append(alarmInfo.toStringVal() + ","); + } + sb.delete(sb.toString().length() - 1, sb.toString().length()); + } + return sb.toString(); + } +} diff --git a/src/com/nis/nmsclient/model/AlarmInfo.java b/src/com/nis/nmsclient/model/AlarmInfo.java new file mode 100644 index 0000000..58d85e6 --- /dev/null +++ b/src/com/nis/nmsclient/model/AlarmInfo.java @@ -0,0 +1,184 @@ +package com.nis.nmsclient.model; + +/** + * 监测信息报警相关信息实体 + * + */ +public class AlarmInfo { + /** + * 告警设置id + */ + private Long id; + /** + * 监测设置id + */ + private Long setInfoId; + /** + * 监测类型 + */ + private String checkType; + /** + * 进程设置名称 + */ + private String processIden; + /** + * 字段Id + */ + private Long metadataId; + /** + * 字段描述 + */ + private String filedCommonts; + /** + * 字段序号 + */ + private Integer showNum; + /** + * 报警状态 + */ + private String policeState; + /** + * 报警值 + */ + private String policeValue; + /** + * 报警单位 + */ + private String policeUnit; + /** + * 报警比较符:针对number型数据>、<、>=、<=、= 针对字符串类型数据equal、 include、exclude + */ + private String policeSysmbols; + /** + * 报警等级 + */ + private Integer policeLevel; + /** + * 设置告警时,指定多个标识符(如多个盘符、多个CPU、多个网卡),如硬盘使用率,空:所有盘存在一个盘使用率超过告警值,则告警;all:所有盘总的使用率超过告警值,则告警;指定多个盘符:指定盘存在一个盘使用率超过告警值,则告警 + */ + private String marker; + /** + * 标识符对应字段在metadata表中的id + */ + private Integer markerFiledId;; + /** + * 标识符对应字段在metadata表中的showNum + */ + private Integer markerFiledShowNum; + + + public Long getSetInfoId() { + return setInfoId; + } + public void setSetInfoId(Long setInfoId) { + this.setInfoId = setInfoId; + } + public Long getMetadataId() { + return metadataId; + } + public void setMetadataId(Long metadataId) { + this.metadataId = metadataId; + } + public Integer getShowNum() { + return showNum; + } + public void setShowNum(Integer showNum) { + this.showNum = showNum; + } + public String getPoliceState() { + return policeState; + } + public void setPoliceState(String policeState) { + this.policeState = policeState; + } + public String getPoliceUnit() { + return policeUnit; + } + public void setPoliceUnit(String policeUnit) { + this.policeUnit = policeUnit; + } + public String getPoliceSysmbols() { + return policeSysmbols; + } + public void setPoliceSysmbols(String policeSysmbols) { + this.policeSysmbols = policeSysmbols; + } + + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + public Integer getPoliceLevel() { + return policeLevel; + } + public void setPoliceLevel(Integer policeLevel) { + this.policeLevel = policeLevel; + } + public String getCheckType() { + return checkType; + } + public void setCheckType(String checkType) { + this.checkType = checkType; + } + public String getProcessIden() { + return processIden; + } + public void setProcessIden(String processIden) { + this.processIden = processIden; + } + public String getFiledCommonts() { + return filedCommonts; + } + public void setFiledCommonts(String filedCommonts) { + this.filedCommonts = filedCommonts; + } + public String getPoliceValue() { + return policeValue; + } + public void setPoliceValue(String policeValue) { + this.policeValue = policeValue; + } + + public String toString() { + return "showNum=" + showNum + ",policeSysmbols=" + policeSysmbols + + ",policeValue=" + policeValue + ",policeLevel=" + policeLevel; + } + + public String toStringVal(){ + return showNum + "|" + policeSysmbols + "|" + policeValue + "|" + + policeLevel + "|" + filedCommonts; + } + + public String getMarker() + { + return marker; + } + + public void setMarker(String marker) + { + this.marker = marker; + } + + public Integer getMarkerFiledId() + { + return markerFiledId; + } + + public void setMarkerFiledId(Integer markerFiledId) + { + this.markerFiledId = markerFiledId; + } + + public Integer getMarkerFiledShowNum() + { + return markerFiledShowNum; + } + + public void setMarkerFiledShowNum(Integer markerFiledShowNum) + { + this.markerFiledShowNum = markerFiledShowNum; + } + +} diff --git a/src/com/nis/nmsclient/model/CommandPO.java b/src/com/nis/nmsclient/model/CommandPO.java new file mode 100644 index 0000000..0644924 --- /dev/null +++ b/src/com/nis/nmsclient/model/CommandPO.java @@ -0,0 +1,86 @@ +package com.nis.nmsclient.model; + +public class CommandPO { + /** + * ID + */ + private Long execId; + /** + * 类型:4 命令执行,6 升级 + */ + private long execType; + /** + * 升级文件存放目录 + */ + private String srcPath; + /** + * 命令名称 + */ + private String commandName; + /** + * 命令参数 + */ + private String commandParam; + /** + * 执行状态:4下发任务(40 下发成功,41下发失败),5杀进程(50成功,51失败)、6备份、7更新(覆盖) 、8启动进程 + */ + private long execState; + /** + * 恢复版本 + */ + private Long execVersion; + /** + * 是否周期任务 + */ + private long isLoop; + + public Long getExecId() { + return execId; + } + public void setExecId(Long execId) { + this.execId = execId; + } + public long getExecType() { + return execType; + } + public void setExecType(long execType) { + this.execType = execType; + } + public String getSrcPath() { + return srcPath; + } + public void setSrcPath(String srcPath) { + this.srcPath = srcPath; + } + public String getCommandName() { + return commandName; + } + public void setCommandName(String commandName) { + this.commandName = commandName; + } + public String getCommandParam() { + return commandParam; + } + public void setCommandParam(String commandParam) { + this.commandParam = commandParam; + } + public long getExecState() { + return execState; + } + public void setExecState(long execState) { + this.execState = execState; + } + public Long getExecVersion() { + return execVersion; + } + public void setExecVersion(Long execVersion) { + this.execVersion = execVersion; + } + public long getIsLoop() { + return isLoop; + } + public void setIsLoop(long isLoop) { + this.isLoop = isLoop; + } + +} diff --git a/src/com/nis/nmsclient/model/ParamBackup.java b/src/com/nis/nmsclient/model/ParamBackup.java new file mode 100644 index 0000000..5deac2a --- /dev/null +++ b/src/com/nis/nmsclient/model/ParamBackup.java @@ -0,0 +1,52 @@ +package com.nis.nmsclient.model; + +/** + * 备份命令的参数实体类 + * @date Mar 23, 2012 + * @author zhenzhen + * @version + */ +public class ParamBackup{ + /** + * 需要备份的文件或目录 + */ + private String backup = null; + /** + * 备份文件到的目的路径 + */ + private String backupTo = null; + /** + * 排除的文件或目录,即不需要备份的,如果是相对路径,则相对需要备份的文件或目录 + */ + private String[] except = null; + /** + * 备份压缩包时:Y 按绝对路径压缩,N 按进入备份目录压缩(这个属性只针对Linux有效,Windows下只按进入备份目录压缩) + */ + private String isAbs = null; + + public String getBackup() { + return backup; + } + public void setBackup(String backup) { + this.backup = backup; + } + public String getBackupTo() { + return backupTo; + } + public void setBackupTo(String backupTo) { + this.backupTo = backupTo; + } + public String[] getExcept() { + return except; + } + public void setExcept(String[] except) { + this.except = except; + } + public String getIsAbs() { + return isAbs; + } + public void setIsAbs(String isAbs) { + this.isAbs = isAbs; + } + +} \ No newline at end of file diff --git a/src/com/nis/nmsclient/model/ParamCmdExec.java b/src/com/nis/nmsclient/model/ParamCmdExec.java new file mode 100644 index 0000000..c66b6a5 --- /dev/null +++ b/src/com/nis/nmsclient/model/ParamCmdExec.java @@ -0,0 +1,111 @@ +package com.nis.nmsclient.model; + +/** + * 命令执行(启动命令)的参数实体类 + * @date Mar 23, 2012 + * @author zhenzhen + * @version + */ +public class ParamCmdExec { + /** + * 执行文件或命令 + */ + private String execCmd; + /** + * 执行文件或命令的参数序列 + */ + private String[] execParams; + /** + * 该命令是否强制执行:Y是,N否 + */ + private String forceExec; + /** + * 常驻内存标识: Y是,N否 + */ + private String residentFlag; + /** + * 存放执行结果标识的文件:1、常驻内存的,写入PID,2、非常驻的,写执行结果:结果标识(0 成功 1 失败)|结果描述 + */ + private String execResult; + /** + * 回传标识: Y是,N否 + */ + private String returnFlag; + /** + * 回传文件或目录路径 + */ + private String returnPath; + /** + * 最终结果获取最大等待时间(单位:秒) + */ + private String maxWaitTime; + /** + * 执行文件或命令的用户名(只针对Linux有效) + */ + private String username; + /** + * 执行用户的密码(只针对Linux有效) + */ + private String param1; + + public String getExecCmd() { + return execCmd; + } + public void setExecCmd(String execCmd) { + this.execCmd = execCmd; + } + public String getForceExec() { + return forceExec; + } + public void setForceExec(String forceExec) { + this.forceExec = forceExec; + } + public String getResidentFlag() { + return residentFlag; + } + public void setResidentFlag(String residentFlag) { + this.residentFlag = residentFlag; + } + public String getExecResult() { + return execResult; + } + public void setExecResult(String execResult) { + this.execResult = execResult; + } + public String getReturnFlag() { + return returnFlag; + } + public void setReturnFlag(String returnFlag) { + this.returnFlag = returnFlag; + } + public String getReturnPath() { + return returnPath; + } + public void setReturnPath(String returnPath) { + this.returnPath = returnPath; + } + public String getMaxWaitTime() { + return maxWaitTime; + } + public void setMaxWaitTime(String maxWaitTime) { + this.maxWaitTime = maxWaitTime; + } + public String getUsername() { + return username; + } + public void setUsername(String username) { + this.username = username; + } + public String[] getExecParams() { + return execParams; + } + public void setExecParams(String[] execParams) { + this.execParams = execParams; + } + public String getParam1() { + return param1; + } + public void setParam1(String param1) { + this.param1 = param1; + } +} diff --git a/src/com/nis/nmsclient/model/ParamCoverUpdate.java b/src/com/nis/nmsclient/model/ParamCoverUpdate.java new file mode 100644 index 0000000..3d731d4 --- /dev/null +++ b/src/com/nis/nmsclient/model/ParamCoverUpdate.java @@ -0,0 +1,62 @@ +package com.nis.nmsclient.model; + +/** + * 覆盖更新的参数实体类 + * @date Mar 23, 2012 + * @author zhenzhen + * @version + */ +public class ParamCoverUpdate{ + /** + * 指定更新需要的文件 + */ + private String source = null; + /** + * 指定文件覆盖目录 + */ + private String cover = null; + /** + * 是否创建覆盖目录 + */ + private String isCreateCover = null; + /** + * 删除的文件或目录,如果是相对路径,则相对需要更新的目录 + */ + private String[] delete = null; + /** + * 如果更新源文件是个压缩包:Y 按绝对路径解压即在根目录下解压,N 按进入备份目录解压(这个属性只针对Linux有效,Windows下只按进入备份目录解压) + */ + private String isAbs = null; + + public String getSource() { + return source; + } + public void setSource(String source) { + this.source = source; + } + public String getCover() { + return cover; + } + public void setCover(String cover) { + this.cover = cover; + } + public String getIsCreateCover() { + return isCreateCover; + } + public void setIsCreateCover(String isCreateCover) { + this.isCreateCover = isCreateCover; + } + public String[] getDelete() { + return delete; + } + public void setDelete(String[] delete) { + this.delete = delete; + } + public String getIsAbs() { + return isAbs; + } + public void setIsAbs(String isAbs) { + this.isAbs = isAbs; + } + +} \ No newline at end of file diff --git a/src/com/nis/nmsclient/model/ParamFilePush.java b/src/com/nis/nmsclient/model/ParamFilePush.java new file mode 100644 index 0000000..e775e22 --- /dev/null +++ b/src/com/nis/nmsclient/model/ParamFilePush.java @@ -0,0 +1,81 @@ +package com.nis.nmsclient.model; + +/** + * 文件推送的参数实体类 + * @date Mar 23, 2012 + * @author zhenzhen + * @version + */ +public class ParamFilePush { + /** + * 推送文件名 + */ + private String fileName; + /** + * 推送目的地 + */ + private String destPath; + /** + * 是否覆盖:Y是,N否 + */ + private String isCover; + /** + * 推送文件的属主(只针对Linux有效) + */ + private String username; + /** + * 属主密码(只针对Linux有效) + */ + private String param1; + /** + * 推送文件的属组(只针对Linux有效) + */ + private String groupName; + /** + * 推送文件拥有的权限(只针对Linux有效) + */ + private String permisson; + + public String getFileName() { + return fileName; + } + public void setFileName(String fileName) { + this.fileName = fileName; + } + public String getDestPath() { + return destPath; + } + public void setDestPath(String destPath) { + this.destPath = destPath; + } + public String getIsCover() { + return isCover; + } + public void setIsCover(String isCover) { + this.isCover = isCover; + } + public String getUsername() { + return username; + } + public void setUsername(String username) { + this.username = username; + } + public String getGroupName() { + return groupName; + } + public void setGroupName(String groupName) { + this.groupName = groupName; + } + public String getPermisson() { + return permisson; + } + public void setPermisson(String permisson) { + this.permisson = permisson; + } + public String getParam1() { + return param1; + } + public void setParam1(String param1) { + this.param1 = param1; + } +} diff --git a/src/com/nis/nmsclient/model/ParamUpgrade.java b/src/com/nis/nmsclient/model/ParamUpgrade.java new file mode 100644 index 0000000..891bbf1 --- /dev/null +++ b/src/com/nis/nmsclient/model/ParamUpgrade.java @@ -0,0 +1,174 @@ +package com.nis.nmsclient.model; + + +/** + * 升级命令的参数实体类 + * @date Mar 23, 2012 + * @author zhenzhen + * @version + */ +public class ParamUpgrade { + /** + * 指定更新需要的文件,如果是相对路径,则相对推送目的地 + */ + private String fileName = null; + /** + * 指定文件覆盖目录 + */ + private String cover = null; + /** + * 是否创建覆盖目录 + */ + private String isCreateCover = null; + /** + * 如果更新源文件是个压缩包:Y 按绝对路径解压即在根目录下解压,N 按进入备份目录解压(这个属性只针对Linux有效,Windows下只按进入备份目录解压) + */ + private String isAbs = null; + /** + * 需要删除的目录,如果是相对路径,则相对覆盖目录 + */ + private String [] delete = null; + /** + * 该命令是否强制执行:Y是,N否 + */ + private String forceExec; + /** + * 文件的属主或运行的用户(只针对Linux有效) + */ + private String username; + /** + * 用户密码(只针对Linux有效) + */ + private String param1; + /** + * 文件的属组(只针对Linux有效) + */ + private String groupName; + /** + * 权限设置 + */ + private String permisson = null; + //以上是升级用到的参数属性,以下是升级和恢复都有的参数属性 + /** + * 备份目录,如果是相对路径,则相对覆盖目录 + */ + private ParamBackup [] backups = null; + /** + * 恢复目录,逆向任务时使用 + */ + private ParamCoverUpdate[] recoverys; + /** + * 进程PID文件全路径 + */ + private String pidFile = null; + /** + * 进程启动文件全路径 + */ + private String startupFile = null; + /** + * 执行文件的参数序列 + */ + private String[] execParams; + /** + * 最终结果获取最大等待时间(单位:秒) + */ + private String maxWaitTime; + + public String getFileName() { + return fileName; + } + public void setFileName(String fileName) { + this.fileName = fileName; + } + public String getCover() { + return cover; + } + public void setCover(String cover) { + this.cover = cover; + } + public ParamBackup[] getBackups() { + return backups; + } + public void setBackups(ParamBackup[] backups) { + this.backups = backups; + } + public String getPidFile() { + return pidFile; + } + public void setPidFile(String pidFile) { + this.pidFile = pidFile; + } + public String getStartupFile() { + return startupFile; + } + public void setStartupFile(String startupFile) { + this.startupFile = startupFile; + } + public String[] getDelete() { + return delete; + } + public void setDelete(String[] delete) { + this.delete = delete; + } + public String getIsCreateCover() { + return isCreateCover; + } + public void setIsCreateCover(String isCreateCover) { + this.isCreateCover = isCreateCover; + } + public String getUsername() { + return username; + } + public void setUsername(String username) { + this.username = username; + } + public String getPermisson() { + return permisson; + } + public void setPermisson(String permisson) { + this.permisson = permisson; + } + public String getGroupName() { + return groupName; + } + public void setGroupName(String groupName) { + this.groupName = groupName; + } + public String getIsAbs() { + return isAbs; + } + public void setIsAbs(String isAbs) { + this.isAbs = isAbs; + } + public String getForceExec() { + return forceExec; + } + public void setForceExec(String forceExec) { + this.forceExec = forceExec; + } + public String getMaxWaitTime() { + return maxWaitTime; + } + public void setMaxWaitTime(String maxWaitTime) { + this.maxWaitTime = maxWaitTime; + } + public void setExecParams(String[] execParams) { + this.execParams = execParams; + } + public String[] getExecParams() { + return execParams; + } + public ParamCoverUpdate[] getRecoverys() { + return recoverys; + } + public void setRecoverys(ParamCoverUpdate[] recoverys) { + this.recoverys = recoverys; + } + public String getParam1() { + return param1; + } + public void setParam1(String param1) { + this.param1 = param1; + } + +} diff --git a/src/com/nis/nmsclient/model/ReturnFilePO.java b/src/com/nis/nmsclient/model/ReturnFilePO.java new file mode 100644 index 0000000..e781f42 --- /dev/null +++ b/src/com/nis/nmsclient/model/ReturnFilePO.java @@ -0,0 +1,106 @@ +package com.nis.nmsclient.model; + +import java.util.Date; + +public class ReturnFilePO { + /** + * ID + */ + private Long taskId; + /** + * 类型:4 命令执行,6 升级 + */ + private long taskType; + /** + * 唯一标志一台物理机(类似于IP) + */ + private long uuid; + /** + * 回传路径集: key 文件实际路径 value 文件别名 + */ +// private Map filePathMap; + /** + * 当前要回传的文件 + */ +// private File curRetrunFile; + /** + * 回传文件名(统一处理后一个任务只有一个回传文件) + */ + private String returnFileName; + /** + * 回传状态:0 成功,1 失败 + */ + private long state; + /** + * 开始时间 + */ + private Date startTime; + /** + * 结束时间 + */ + private Date endTime; + /** + * 是否循环任务 + */ + private long isLoop; + /** + * 回传文件的结果描述 + */ + private String resDesc; + + public Long getTaskId() { + return taskId; + } + public void setTaskId(Long taskId) { + this.taskId = taskId; + } + public long getTaskType() { + return taskType; + } + public void setTaskType(long taskType) { + this.taskType = taskType; + } + public long getState() { + return state; + } + public void setState(long state) { + this.state = state; + } + public Date getStartTime() { + return startTime; + } + public void setStartTime(Date startTime) { + this.startTime = startTime; + } + public Date getEndTime() { + return endTime; + } + public void setEndTime(Date endTime) { + this.endTime = endTime; + } + public long getIsLoop() { + return isLoop; + } + public void setIsLoop(long isLoop) { + this.isLoop = isLoop; + } + public String getResDesc() { + return resDesc; + } + public void setResDesc(String resDesc) { + this.resDesc = resDesc; + } + public String getReturnFileName() { + return returnFileName; + } + public void setReturnFileName(String returnFileName) { + this.returnFileName = returnFileName; + } + public long getUuid() { + return uuid; + } + public void setUuid(long uuid) { + this.uuid = uuid; + } + +} diff --git a/src/com/nis/nmsclient/model/SetInfo.java b/src/com/nis/nmsclient/model/SetInfo.java new file mode 100644 index 0000000..c0e1338 --- /dev/null +++ b/src/com/nis/nmsclient/model/SetInfo.java @@ -0,0 +1,272 @@ +package com.nis.nmsclient.model; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang.builder.ReflectionToStringBuilder; + +import com.nis.nmsclient.common.Contants; + +/** + * 客户端用到的监测设置信息实体 + * + */ +public class SetInfo { + /** + * 监测设置信息ID + */ + private Long id; + /** + * 检测类型 + */ + private String checkTypeName;//如:CPU、DISK等 + /** + * 检测类型的ID,预留 + */ + private Long checkTypeId; + /** + * 最大测试次数 + */ + private Long checkMaxTimes; + /** + * 时间间隔(单位:分钟) + */ + private Long checkGap; + /** + * 超时时间(单位:秒) + */ + private Long checkOutTime; + /** + * 监测状态:0无效;1有效 + */ + private String checkState; + /** + * 监测方式:0主动(DC执行),1被动(NC执行) + */ + private String checkWay; + /** + * 设置标志 + */ + private String processIden; + /** + * 进程PID存放文件 + */ + private String processFile; + /** + * 进程执行文件 + */ + private String processPath; + /** + * 是否系统启动(NMSAgent启动/第三方自己启动);默认0自启动;1NMSAgent启动 + */ + private String IsControlStart; + /** + * 控制启动时间 + */ + private Long controlStartTime; + /** + *上传数据时间间隔单位分钟:不能为空,默认15分钟。监测数据上传到NMSServer周期。 + */ + private Long uploadGap; + + /** + * 计划检测时间:针对当前配置信息首次执行时间 + */ + private Long planCheckTime; + /** + * 是否预置监测,0是,1否 + */ + private String isSchedule; + /** + * 进程搜索关键字 + */ + private String processSearchKeyCode; + + // ====== 以下信息仅供DC端使用,这里添加是为了不出现WARN信息 + private String nodeGroupsId; + private String nodeIpsId; + private Long viewLevel; + private String nodeIp2; + private Long isSNMP; + + // ======= 保存最后合并的临时结果文件的检测时间(仅用于NC) + private Long lastMergeDetecTime; + + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + public String getCheckTypeName() { + return checkTypeName; + } + public void setCheckTypeName(String checkTypeName) { + this.checkTypeName = checkTypeName; + } + public Long getCheckTypeId() { + return checkTypeId; + } + public Long getCheckMaxTimes() { + return checkMaxTimes; + } + public void setCheckMaxTimes(Long checkMaxTimes) { + this.checkMaxTimes = checkMaxTimes; + } + public Long getCheckGap() { + return checkGap; + } + public void setCheckGap(Long checkGap) { + this.checkGap = checkGap; + } + public Long getCheckOutTime() { + return checkOutTime; + } + public void setCheckOutTime(Long checkOutTime) { + this.checkOutTime = checkOutTime; + } + public String getCheckState() { + return checkState; + } + public void setCheckState(String checkState) { + this.checkState = checkState; + } + public String getProcessIden() { + return processIden; + } + public void setProcessIden(String processIden) { + this.processIden = processIden; + } + public String getProcessFile() { + return processFile; + } + public void setProcessFile(String processFile) { + this.processFile = processFile; + } + public String getProcessPath() { + return processPath; + } + public void setProcessPath(String processPath) { + this.processPath = processPath; + } + public void setCheckTypeId(Long checkTypeId) { + this.checkTypeId = checkTypeId; + } + public String getCheckWay() { + return checkWay; + } + public void setCheckWay(String checkWay) { + this.checkWay = checkWay; + } + + public String[] getValArr(Long uuid, String dataFileDir) { + List list = new ArrayList(); + list.add("pubInfo=" + uuid + "," + id + "," + checkTypeName + "," + processIden); + list.add("checkState=" + checkState); + //list.add("checkWay=" + checkWay); + //list.add("isControlStart=" + IsControlStart); + //list.add("controlStartTime=" + controlStartTime); + list.add("checkGap=" + checkGap); + list.add("checkOutTime=" + checkOutTime); + list.add("checkMaxTimes=" + checkMaxTimes); + //list.add("processFile=" + processFile); + //list.add("processPath=" + processPath); + list.add("planCheckTime=" + planCheckTime); + list.add("uploadGap=" + uploadGap); + list.add("dataFileDir=" + dataFileDir); + + try { + if("1".equals(isSchedule)) { // 第三方监测 + File dataDir = new File(dataFileDir); + File tempDataDir = new File(Contants.localTempDataIncomingPath, dataDir.getName()); + list.add("tempDataFileDir=" + tempDataDir.getCanonicalPath()); + } + } catch (IOException e) { + e.printStackTrace(); + } + + String[] val = new String[list.size()]; + return list.toArray(val); + } + public String getIsControlStart() { + return IsControlStart; + } + public void setIsControlStart(String isControlStart) { + IsControlStart = isControlStart; + } + public Long getUploadGap() { + return uploadGap; + } + public void setUploadGap(Long uploadGap) { + this.uploadGap = uploadGap; + } + public String getIsSchedule() { + return isSchedule; + } + public void setIsSchedule(String isSchedule) { + this.isSchedule = isSchedule; + } + public Long getControlStartTime() { + return controlStartTime; + } + public void setControlStartTime(Long controlStartTime) { + this.controlStartTime = controlStartTime; + } + public Long getPlanCheckTime() { + return planCheckTime; + } + public void setPlanCheckTime(Long planCheckTime) { + this.planCheckTime = planCheckTime; + } + public String getProcessSearchKeyCode() { + return processSearchKeyCode; + } + public void setProcessSearchKeyCode(String processSearchKeyCode) { + this.processSearchKeyCode = processSearchKeyCode; + } + public String getNodeGroupsId() { + return nodeGroupsId; + } + public void setNodeGroupsId(String nodeGroupsId) { + this.nodeGroupsId = nodeGroupsId; + } + public String getNodeIpsId() { + return nodeIpsId; + } + public void setNodeIpsId(String nodeIpsId) { + this.nodeIpsId = nodeIpsId; + } + public Long getViewLevel() { + return viewLevel; + } + public void setViewLevel(Long viewLevel) { + this.viewLevel = viewLevel; + } + public String getNodeIp2() { + return nodeIp2; + } + public void setNodeIp2(String nodeIp2) { + this.nodeIp2 = nodeIp2; + } + public Long getIsSNMP() { + return isSNMP; + } + public void setIsSNMP(Long isSNMP) { + this.isSNMP = isSNMP; + } + public void setLastMergeDetecTime(Long lastMergeDetecTime) { + this.lastMergeDetecTime = lastMergeDetecTime; + } + public Long getLastMergeDetecTime() { + return lastMergeDetecTime; + } + + @Override + public String toString() { + return ReflectionToStringBuilder.toString(this); + } + + +} diff --git a/src/com/nis/nmsclient/model/Task1.java b/src/com/nis/nmsclient/model/Task1.java new file mode 100644 index 0000000..32950fb --- /dev/null +++ b/src/com/nis/nmsclient/model/Task1.java @@ -0,0 +1,49 @@ +package com.nis.nmsclient.model; + +/** + * 任务实体类:1 文件推送 + * + */ +public class Task1 { + /** + * 任务ID + */ + private Long taskId; + /** + * 任务类型:1 文件推送,2 非流文本数据获取,3 流文本数据获取,4 命令执行,5 shell注册 + */ + private long taskType; + /** + * 推送文件参数设置 + */ + private String taskParam; + /** + * 重新执行,原任务ID + */ + private Long oldTaskId; + + public Long getTaskId() { + return taskId; + } + public void setTaskId(Long taskId) { + this.taskId = taskId; + } + public long getTaskType() { + return taskType; + } + public void setTaskType(long taskType) { + this.taskType = taskType; + } + public String getTaskParam() { + return taskParam; + } + public void setTaskParam(String taskParam) { + this.taskParam = taskParam; + } + public Long getOldTaskId() { + return oldTaskId; + } + public void setOldTaskId(Long oldTaskId) { + this.oldTaskId = oldTaskId; + } +} diff --git a/src/com/nis/nmsclient/model/Task4.java b/src/com/nis/nmsclient/model/Task4.java new file mode 100644 index 0000000..302252c --- /dev/null +++ b/src/com/nis/nmsclient/model/Task4.java @@ -0,0 +1,166 @@ +package com.nis.nmsclient.model; + + +/** + * 任务实体类:4 命令执行 + * + */ +public class Task4 { + /** + * 任务ID + */ + private Long taskId; + /** + * 任务类型:1 文件推送,2 非流文本数据获取,3 流文本数据获取,4 命令执行,5 shell注册 + */ + private long taskType; + /** + * 命令类型:1 Agent原生支持命令,2 脚本,3 shell命令 + */ + private long commandType; + /** + * 命令名称 + */ + private String commandName; + /** + * 命令参数 + */ + private String commandParam; + /** + * 脚本路径(已无用) + */ + private String scriptPath; + /** + * 执行状态:4下发任务(40 下发成功,41下发失败),5杀进程(50成功,51失败)、6备份、7更新(覆盖) 、8启动进程 + */ + private long state; + /** + * 执行时间 + */ + private Long startTime; + /** + * 结束时间 + */ + private Long endTime; + /** + * 是否循环任务: 0 非周期, 1 周期,默认是0 + */ + private long isLoop; + /** + * 如果是循环任务,循环周期 + */ + private long loopDelay; + /** + * 任务状态:6撤销执行 + */ + private Long missionState; + /** + * 重新执行,原任务ID + */ + private Long oldTaskId; + + public Long getTaskId() { + return taskId; + } + + public void setTaskId(Long taskId) { + this.taskId = taskId; + } + + public long getTaskType() { + return taskType; + } + + public void setTaskType(long taskType) { + this.taskType = taskType; + } + + public long getCommandType() { + return commandType; + } + + public void setCommandType(long commandType) { + this.commandType = commandType; + } + + public long getState() { + return state; + } + + public void setState(long state) { + this.state = state; + } + + public String getCommandName() { + return commandName; + } + + public void setCommandName(String commandName) { + this.commandName = commandName; + } + + public String getCommandParam() { + return commandParam; + } + + public void setCommandParam(String commandParam) { + this.commandParam = commandParam; + } + + public String getScriptPath() { + return scriptPath; + } + + public void setScriptPath(String scriptPath) { + this.scriptPath = scriptPath; + } + + public Long getStartTime() { + return startTime; + } + + public void setStartTime(Long startTime) { + this.startTime = startTime; + } + + public Long getEndTime() { + return endTime; + } + + public void setEndTime(Long endTime) { + this.endTime = endTime; + } + + public long getIsLoop() { + return isLoop; + } + + public void setIsLoop(long isLoop) { + this.isLoop = isLoop; + } + + public long getLoopDelay() { + return loopDelay; + } + + public void setLoopDelay(long loopDelay) { + this.loopDelay = loopDelay; + } + + public Long getMissionState() { + return missionState; + } + + public void setMissionState(Long missionState) { + this.missionState = missionState; + } + + public Long getOldTaskId() { + return oldTaskId; + } + + public void setOldTaskId(Long oldTaskId) { + this.oldTaskId = oldTaskId; + } + +} diff --git a/src/com/nis/nmsclient/model/Task6.java b/src/com/nis/nmsclient/model/Task6.java new file mode 100644 index 0000000..06ddec7 --- /dev/null +++ b/src/com/nis/nmsclient/model/Task6.java @@ -0,0 +1,121 @@ +package com.nis.nmsclient.model; + + +/** + * 任务实体类:6 升级 + * + */ +public class Task6 { + /** + * 任务ID + */ + private Long taskId; + /** + * 任务类型:1 文件推送,4 命令执行,5 shell注册,6 升级 + */ + private long taskType; + /** + * 命令类型:4 Agent原生支持命令 + */ + private long commandType; + /** + * 命令名称 + */ + private String commandName; + /** + * 命令参数 + */ + private String commandParam; + /** + * 执行状态:4下发任务(40 下发成功,41下发失败),5杀进程(50成功,51失败)、6备份、7更新(覆盖) 、8启动进程 + */ + private Long state; + /** + * 如果是恢复(逆向任务),则为恢复到的版本(恢复到的任务ID)。判断它是否为空,来确定是否逆向任务 + */ + private Long version; + /** + * 升级时间 + */ + private Long upgradeTime; + /** + * 全局权限用户名(未来) + */ + private String username; + /** + * 全局权限密码(未来 约定加密方式) + */ + private String userpwd; + /** + * 重新执行,原任务ID + */ + private Long oldTaskId; + + public Long getTaskId() { + return taskId; + } + public void setTaskId(Long taskId) { + this.taskId = taskId; + } + public long getTaskType() { + return taskType; + } + public void setTaskType(long taskType) { + this.taskType = taskType; + } + public long getCommandType() { + return commandType; + } + public void setCommandType(long commandType) { + this.commandType = commandType; + } + public String getCommandName() { + return commandName; + } + public void setCommandName(String commandName) { + this.commandName = commandName; + } + public String getCommandParam() { + return commandParam; + } + public void setCommandParam(String commandParam) { + this.commandParam = commandParam; + } + public Long getState() { + return state; + } + public void setState(Long state) { + this.state = state; + } + public Long getVersion() { + return version; + } + public void setVersion(Long version) { + this.version = version; + } + public Long getUpgradeTime() { + return upgradeTime; + } + public void setUpgradeTime(Long upgradeTime) { + this.upgradeTime = upgradeTime; + } + public String getUsername() { + return username; + } + public void setUsername(String username) { + this.username = username; + } + public String getUserpwd() { + return userpwd; + } + public void setUserpwd(String userpwd) { + this.userpwd = userpwd; + } + public Long getOldTaskId() { + return oldTaskId; + } + public void setOldTaskId(Long oldTaskId) { + this.oldTaskId = oldTaskId; + } + +} diff --git a/src/com/nis/nmsclient/thread/WritePidThread.java b/src/com/nis/nmsclient/thread/WritePidThread.java new file mode 100644 index 0000000..8126978 --- /dev/null +++ b/src/com/nis/nmsclient/thread/WritePidThread.java @@ -0,0 +1,66 @@ +package com.nis.nmsclient.thread; + + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.lang.management.ManagementFactory; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; +import com.nis.nmsclient.common.Contants; + +public class WritePidThread implements Runnable{ + + @Override + public void run() { + String SYSTEM_PATH = System.getProperty("user.dir"); +// Thread.currentThread().setName("写PID线程"); + Thread.currentThread().setName("Write The PID Thread"); + Logger logger = Logger.getLogger(WritePidThread.class); + + /* 获取程序运行PID */ + String path = Contants.localAgentPidFile;//2015-11-25:之前一直写的是"NMSClientPid.temp",不对配置的是agentPid.temp + String name = ManagementFactory.getRuntimeMXBean().getName(); + logger.info("当前程序PID:>"+(name.split("@")[0])); + + /* 判断系统类型是否写文件 */ + String os = System.getProperty("os.name"); + if(os!=null && !os.toLowerCase().startsWith("windows")){ + logger.info("非Windows系统 结束执行"); + return ; + } + /* 获取输出文件并检查文件路径是否存在 */ + File file = new File(path); + if(!file.getParentFile().exists()){ + file.getParentFile().mkdirs(); + } + + /* 将PID写入文件 */ + FileWriter writer = null; + try { + writer = new FileWriter(file); + writer.write(name.split("@")[0]); + writer.flush(); + logger.info("写PID完成"); + } catch (IOException e) { + logger.error("Write PID failure", e); + }finally{ + try { + if(writer!=null) + writer.close(); + writer = null; + } catch (IOException e) { + logger.error("", e); + } + logger.info("线程关闭"); + } + } + public static void main(String [] args) { + new Thread(new WritePidThread()).start(); + } + public static void pl (Object obj) { + System.out.println(obj==null?null:obj.toString()); + } + +} diff --git a/src/com/nis/nmsclient/thread/alarm/AlarmPO.java b/src/com/nis/nmsclient/thread/alarm/AlarmPO.java new file mode 100644 index 0000000..e1495ed --- /dev/null +++ b/src/com/nis/nmsclient/thread/alarm/AlarmPO.java @@ -0,0 +1,146 @@ +package com.nis.nmsclient.thread.alarm; + + +public class AlarmPO { + /** + * 监测ID + */ + private long id; + /** + * 监测类型 + */ + private String type; + /** + * 监测设置名称 + */ + private String procIden; + /** + * 时间间隔(单位:分钟) + */ + private long checkGap; + /** + * 是否是进程 + */ + private boolean isproc; + /** + * 进程路径与名称 + */ + private String proc; + /** + * PID文件 + */ + private String pidFileStr; + /** + * 进程搜索关键字 + */ + private String processSearchKeyCode; + /** + * 控制启动时间 + */ + private Long controlStartTime; + /** + * 是否系统启动(NMSAgent启动/第三方自己启动);默认0自启动;1NMSAgent启动 + */ + private String IsControlStart; + + public AlarmPO() { + super(); + } + + public AlarmPO(long id, String type, String procIden, long checkGap, + boolean isproc, String proc, String pidFileStr, + Long controlStartTime, String processSearchKeyCode, String IsControlStart) { + super(); + this.id = id; + this.type = type; + this.procIden = procIden; + this.checkGap = checkGap; + this.isproc = isproc; + this.proc = proc; + this.pidFileStr = pidFileStr; + this.controlStartTime = controlStartTime; + this.processSearchKeyCode = processSearchKeyCode; + this.IsControlStart = IsControlStart; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getProcIden() { + return procIden; + } + + public void setProcIden(String procIden) { + this.procIden = procIden; + } + + public long getCheckGap() { + return checkGap; + } + + public void setCheckGap(long checkGap) { + this.checkGap = checkGap; + } + + public boolean isIsproc() { + return isproc; + } + + public void setIsproc(boolean isproc) { + this.isproc = isproc; + } + + public String getProc() { + return proc; + } + + public void setProc(String proc) { + this.proc = proc; + } + + public String getPidFileStr() { + return pidFileStr; + } + + public void setPidFileStr(String pidFileStr) { + this.pidFileStr = pidFileStr; + } + + public Long getControlStartTime() { + return controlStartTime; + } + + public void setControlStartTime(Long controlStartTime) { + this.controlStartTime = controlStartTime; + } + + public String getProcessSearchKeyCode() { + return processSearchKeyCode; + } + + public void setProcessSearchKeyCode(String processSearchKeyCode) { + this.processSearchKeyCode = processSearchKeyCode; + } + + public String getIsControlStart() { + return IsControlStart; + } + + public void setIsControlStart(String isControlStart) { + IsControlStart = isControlStart; + } + +} diff --git a/src/com/nis/nmsclient/thread/alarm/AlarmThread.java b/src/com/nis/nmsclient/thread/alarm/AlarmThread.java new file mode 100644 index 0000000..41d989a --- /dev/null +++ b/src/com/nis/nmsclient/thread/alarm/AlarmThread.java @@ -0,0 +1,315 @@ +package com.nis.nmsclient.thread.alarm; + +import java.io.File; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import org.apache.log4j.Logger; + +import com.nis.nmsclient.common.Common; +import com.nis.nmsclient.common.Contants; +import com.nis.nmsclient.config.DetecConfOper; +import com.nis.nmsclient.util.DateUtil; +import com.nis.nmsclient.util.FileUtil; +import com.nis.nmsclient.util.ProcessUtil; +import com.nis.nmsclient.util.Utils; + +/** + * 主动报警线程:针对当前所有有效监测设置进行主动报警 + * 定时监测某设置是否正常生成数据,N次未取到数据后向Server报警,恢复正常后向Server发送提示信息 + * @date Mar 22, 2012 + * @author zhenzhen + * @version + */ +public class AlarmThread implements Runnable{ + Logger logger = Logger.getLogger(AlarmThread.class); + private String name; + + private Map alarmSmMap = new HashMap(); + + public AlarmThread(String name) { + super(); + this.name = name; + } + + public void run() { + Thread.currentThread().setName(name); + + logger.debug("主动预警检查开始 ~~~~~~~"); + try{ + Map alarmPOs = new HashMap(Common + .getAlarmPOs()); + // 清除垃圾数据 + if (alarmSmMap.size() > alarmPOs.size()) { + Iterator it = alarmSmMap.keySet().iterator(); + while (it.hasNext()) { + Long key = it.next(); + if(!alarmPOs.containsKey(key)){ + //alarmSmMap.remove(key); + it.remove();//update by jinsj for 2013-07-08 java.util.ConcurrentModificationException + } + } + + } + Set> entrys = alarmPOs.entrySet(); + int alarmCnt = 0; + StringBuffer alarmDescInfo = new StringBuffer(); + for (Map.Entry entry : entrys) { + // 如果监测进程未启动,则不进行告警检查 + if (entry.getValue().getControlStartTime() != null + && entry.getValue().getControlStartTime() > System + .currentTimeMillis()) { + continue; + } + // 对各监测设置告警状态信息进行赋初值 + Long key = entry.getValue().getId(); + if (alarmSmMap.get(key) == null) { + alarmSmMap.put(key, new AlarmStateMsg(new Date(), 0, + new StringBuffer(), false)); + }else if(alarmSmMap.get(key).getAlarmMsg().length() == 0){ + alarmSmMap.get(key).setStart(new Date()); + } + + boolean flag = alarm(entry.getValue()); + if(flag){ + alarmCnt += 1; + alarmDescInfo.append("\tsetId: " + key + " >> " + entry.getValue().getType() + "_" + entry.getValue().getProcIden()); + alarmDescInfo.append("\n"); + } + } + logger.info("本次预警轮循检查监测设置总数:" + alarmPOs.size() + ",正常:" + + (alarmPOs.size() - alarmCnt) + ",不正常:" + alarmCnt); + if(alarmCnt>0){ + logger.info("本次预警检查不正常的监测如下:\n" + alarmDescInfo.toString()); + } + }catch (Exception e) { + logger.error("Active early warning thread exception:" + Utils.printExceptionStack(e)); + } + logger.debug("主动预警检查结束 ~~~~~~~"); + } + + /** + * 针对一个监测设置的主动预警具体逻辑实现 + * @param alarm + * @return true 告警监测不正常 false 监测正常 + * @throws Exception + */ + public boolean alarm(AlarmPO alarm) throws Exception{ + Long key = alarm.getId(); + String sonDirName = DetecConfOper.getFileName(alarm.getType(), alarm.getProcIden(), null); + StringBuffer sbMsg = new StringBuffer(); + /** + * 1、检查是否存在数据: alarmLevel 0 -- 数据存在,非0 -- 数据不存在 + */ + int alarmLevel = checkDataIsExist(sonDirName, alarm.getCheckGap(), sbMsg); + + /** + * 2、判断进程是否存在:是进程且数据不存在才判断,不是进程如系统类型CPU,则不进行这些操作 + */ + if(alarmLevel!=0 && alarm.isIsproc()){ + if("2".equals(alarm.getIsControlStart())) { // NC周期启动(脚本间断性执行且执行时间较短,通过判断Java定时任务确认进程) + if(Common.containPluginDetecFuture(key)){ // 进程存在 + String temp = sbMsg.toString(); + sbMsg.delete(0, sbMsg.length()); +// sbMsg.append("进程存在,但" + temp); + sbMsg.append("i18n_client.AlarmThread.processExists_n81i" + temp); + alarmLevel = 2; + } else { // 进程不存在 + sbMsg.delete(0, sbMsg.length()); +// sbMsg.append("定时任务“" + alarm.getType() + "”不存在"); + sbMsg.append("i18n_client.AlarmThread.loopMission1_n81i“" + alarm.getType() + "”i18n_client.AlarmThread.loopMission2_n81i"); + alarmLevel = 1; + } + } else { + Object[] objArr = ProcessUtil.checkPidAndGetPid(alarm.getPidFileStr(), alarm.getProcessSearchKeyCode()); + int isExistFlag = Integer.parseInt(objArr[0].toString()); + String pidInfo = objArr[1].toString(); + + if(isExistFlag==0){// 进程不存在(包括PID文件不存在,PID值不存在,搜索关键字也找不到进程) + sbMsg.delete(0, sbMsg.length()); + sbMsg.append(pidInfo); + alarmLevel = 1; + } else {// 进程存在(一个进程或多个进程) + String temp = sbMsg.toString(); + sbMsg.delete(0, sbMsg.length()); +// sbMsg.append("进程存在,但" + temp); + sbMsg.append("i18n_client.AlarmThread.processExists_n81i" + temp); + alarmLevel = 2; + } + } + } + + /** + * 3、统计并发送报警信息 + */ + AlarmStateMsg asMsg= alarmSmMap.get(key); + int times = asMsg.getTimes(); + boolean flag = true; + if (sbMsg.length()>0 && sbMsg.toString().equals(asMsg.getAlarmMsg().toString())) { + times ++ ; + + if (times == Contants.noDataTimes) {// Contants.noDataTime次未取到数据,报警 + AlarmUtil.sendAlarmMsg(alarm, asMsg.getStart(), new Date(), + alarmLevel, Contants.DETECTION_STATUS_ABNORMAL, asMsg + .getAlarmMsg().toString() +// + ",此状态持续了" + times + "次"); + + ",i18n_client.AlarmThread.state_n81i" + times + "i18n_client.AlarmThread.times_n81i"); + asMsg.setAlarmState(true); + } + } else if (sbMsg.length() > 0 + && !sbMsg.toString().equals(asMsg.getAlarmMsg().toString())) { + asMsg.getAlarmMsg().delete(0, asMsg.getAlarmMsg().length()); + asMsg.getAlarmMsg().append(sbMsg.toString()); + times = 1; + } else { + asMsg.getAlarmMsg().delete(0, asMsg.getAlarmMsg().length()); + times = 0; + if(asMsg.isAlarmState()){ + /*AlarmUtil.sendAlarmMsg(alarm, asMsg.getStart(), new Date(), + 99, Contants.DETECTION_STATUS_NORMAL, "恢复正常");*/ + asMsg.setAlarmState(false); + } + flag = false; + } + asMsg.setTimes(times); + alarmSmMap.put(key, asMsg); + + return flag; + } + + /** + * 检查是否存在数据 + * @param sonDirName + * @param checkGap + * @return + */ + private int checkDataIsExist(String sonDirName, long checkGap, StringBuffer sbMsg){ + int alarmLevel = 0; + // ------- 1、先查看当前正在写入的数据文件夹 + File curDir = new File(Contants.localDataFilePath + File.separator + sonDirName); + if(!curDir.exists()){ +// sbMsg.append("数据文件目录“" + curDir.getAbsolutePath() + "”不存在"); + sbMsg.append("i18n_client.AlarmThread.dataFileNotExists1_n81i“" + curDir.getAbsolutePath() + "”i18n_client.AlarmThread.dataFileNotExists2_n81i"); + alarmLevel = 1; + return alarmLevel; + } + long timeMillis = System.currentTimeMillis() - Contants.noDataTimes * checkGap * 60 * 1000; + File[] rightFiles = FileUtil.getFilesAfterMillis(curDir, timeMillis); + if(rightFiles!=null && rightFiles.length>0){// 找到数据,正常 + alarmLevel = 0; + return alarmLevel; + } + + // -------- 2、如果当前正在写入的数据文件夹没有找到符合条件的数据,则查找上传成功后备份到的相应目录 + // 2013-3-28 修改内容:原本只检查当天日期目录是否存在数据,针对监测时间间隔超过一天的存在问题,所以当间隔时间大于等于一天时,改为检查当天日期之前的目录 + String dateDirName = DateUtil.getCurrentDate(DateUtil.YYYYMMDD); + File doneDir = new File(Contants.localDataDonePath + File.separator + sonDirName); + if(doneDir.exists()){ + if(checkGap >= 1440){// --- 检查当天日期及之前的目录 + // 找到指定的日期目录及之前的日期目录,将其降序排列,是为了最先查找当天日期 + File[] dateDirs = FileUtil.sortDescByFileName(FileUtil.getDirsBeforeDateName(doneDir, dateDirName)); + // 在找到的日期目录下检查文件是否存在 + for(File dateDir : dateDirs){ + rightFiles = FileUtil.getFilesAfterMillis(dateDir, timeMillis); + if(rightFiles!=null && rightFiles.length>0){// 在任一目录找到则不再继续查找其他目录 + break; + } + } + }else {// --- 只检查当天日期 + File dateDir = new File(doneDir.getAbsolutePath() + File.separator + dateDirName); + if(dateDir.exists()){ + rightFiles = FileUtil.getFilesAfterMillis(dateDir, timeMillis); + } + } + } + if(rightFiles!=null && rightFiles.length>0){// 找到数据,正常 + alarmLevel = 0; + return alarmLevel; + } + + // -------- 3、查找不完整数据即0大小文件备份到的相应目录 + File[] errorFiles = null; + File errorDir = new File(Contants.localDataErrorPath + File.separator + sonDirName); + if(errorDir.exists()){ + if(checkGap >= 1440){// --- 检查当天日期及之前的目录 + // 找到指定的日期目录及之前的日期目录,将其降序排列,是为了最先查找当天日期 + File[] dateDirs = FileUtil.sortDescByFileName(FileUtil.getDirsBeforeDateName(errorDir, dateDirName)); + // 在找到的日期目录下检查文件是否存在 + for(File dateDir : dateDirs){ + errorFiles = FileUtil.getFilesAfterMillis(dateDir, timeMillis); + if(errorFiles!=null && errorFiles.length>0){// 在任一目录找到则不再继续查找其他目录 + break; + } + } + }else {// --- 只检查当天日期 + File dateDir = new File(doneDir.getAbsolutePath() + File.separator + dateDirName); + if(dateDir.exists()){ + errorFiles = FileUtil.getFilesAfterMillis(errorDir, timeMillis); + } + } + + } + if(errorFiles!=null && errorFiles.length>0){ +// sbMsg.append("监测数据文件大小为0"); + sbMsg.append("i18n_client.AlarmThread.dataSize_n81i"); + alarmLevel = 1; + }else{ +// sbMsg.append("未取到监测数据"); + sbMsg.append("i18n_client.AlarmThread.noDetecateData_n81i"); + alarmLevel = 1; + } + + return alarmLevel; + } + + /** + * 告警检查过程中针对每个监测设置的过程变量状态的封装类 + * @date Mar 22, 2012 + * @author zhenzhen + * @version + */ + class AlarmStateMsg { + private Date start;//告警检查不正常情况的开始时间 + private Integer times;//连续告警次数 + private StringBuffer alarmMsg;//告警信息 + private boolean alarmState;//是否向Server发送了主动告警请求 + + public AlarmStateMsg(Date start, Integer times, StringBuffer alarmMsg, + boolean alarmState) { + super(); + this.start = start; + this.times = times; + this.alarmMsg = alarmMsg; + this.alarmState = alarmState; + } + + public Date getStart() { + return start; + } + public void setStart(Date start) { + this.start = start; + } + public Integer getTimes() { + return times; + } + public void setTimes(Integer times) { + this.times = times; + } + public StringBuffer getAlarmMsg() { + return alarmMsg; + } + public void setAlarmMsg(StringBuffer alarmMsg) { + this.alarmMsg = alarmMsg; + } + public boolean isAlarmState() { + return alarmState; + } + public void setAlarmState(boolean alarmState) { + this.alarmState = alarmState; + } + } + +} diff --git a/src/com/nis/nmsclient/thread/alarm/AlarmUtil.java b/src/com/nis/nmsclient/thread/alarm/AlarmUtil.java new file mode 100644 index 0000000..1c0a76f --- /dev/null +++ b/src/com/nis/nmsclient/thread/alarm/AlarmUtil.java @@ -0,0 +1,79 @@ +package com.nis.nmsclient.thread.alarm; + +import java.util.Date; +import java.util.concurrent.Future; +import org.apache.log4j.Logger; +import com.nis.nmsclient.common.Common; +import com.nis.nmsclient.common.Contants; +import com.nis.nmsclient.config.DetecConfOper; +import com.nis.nmsclient.model.SetInfo; +import com.nis.nmsclient.thread.socket.CommonSocket; +import com.nis.nmsclient.thread.socket.SSLClient; +import com.nis.nmsclient.util.Utils; + +public class AlarmUtil { + static Logger logger = Logger.getLogger(AlarmUtil.class); + + public static void sendAlarmMsg(AlarmPO alarm, Date start, + Date end, int alarmLevel, int state, String alarmMsg,String... showNum) { + sendAlarmMsg(alarm.getId(), alarm.getType(), alarm + .getProcIden(), start, end, alarmLevel, state, alarmMsg,showNum); + } + + public static void sendAlarmMsg(Long alarmId, String checkType, + String procIden, Date start, Date end, int alarmLevel, int state, + String alarmMsg,String... showNum) { + String seprator = Contants.COMMON_MSG_SEPRATOR; + String showAlarmNum=""; + if (showNum!=null && showNum.length>0) + { + showAlarmNum = showNum[0]; + } + String msg = alarmId + seprator + Contants.AGENT_HOST_UUID + seprator + + checkType + seprator + procIden + seprator + start.getTime() + + seprator + end.getTime() + seprator + alarmLevel + seprator + + state + seprator + alarmMsg+ seprator + showAlarmNum; + + Common.service.submit(new SSLClient(Thread.currentThread() + .getName(), CommonSocket.REQ_ALARM, msg)); + + logger.warn("Active alarm level" + alarmLevel + " >> setId: " + alarmId + + "," + checkType + "_" + procIden + ",state: " + state + " > " + + alarmMsg+ ",showNum: " +showAlarmNum); + } + + public static AlarmPO getAlarmPO(SetInfo setInfo){ + AlarmPO alarmPO = new AlarmPO(setInfo.getId(), setInfo + .getCheckTypeName(), setInfo.getProcessIden(), setInfo + .getCheckGap(), DetecConfOper.isProcess(setInfo), DetecConfOper + .getProcess(setInfo), setInfo.getProcessFile(), setInfo + .getControlStartTime(), setInfo.getProcessSearchKeyCode(), + setInfo.getIsControlStart()); + + return alarmPO; + } + + // 向DC发送NC端的异常信息 + public static void sendNMSErrorMsg(ErrorCode errorCode, String errorIp, String errorDesc) { + String seprator = Contants.COMMON_MSG_SEPRATOR; + try { + //异常信息顺序:CODE、发送IP、发生错误IP、发生错误时间、处理状态(1)、错误描述 + String msg = errorCode.toString() + seprator + Utils.getLocalIp() + seprator + errorIp + + seprator + System.currentTimeMillis() + seprator + "1" + + seprator + errorDesc; + + Future future = Common.service.submit(new SSLClient(Thread.currentThread() + .getName(), CommonSocket.REQ_ERROR_INFO, msg)); + + if(errorCode.equals(ErrorCode.ProtListenerError)){ + future.get(); + } + + logger.error("Abnormal information " + errorCode + " >> errorIp: " + errorIp + " > " + + errorDesc); + } catch (Exception e) { + logger.error(e); + } + + } +} diff --git a/src/com/nis/nmsclient/thread/alarm/ErrorCode.java b/src/com/nis/nmsclient/thread/alarm/ErrorCode.java new file mode 100644 index 0000000..0f62cb9 --- /dev/null +++ b/src/com/nis/nmsclient/thread/alarm/ErrorCode.java @@ -0,0 +1,11 @@ +package com.nis.nmsclient.thread.alarm; + +public enum ErrorCode { + ProcessNotExist, //进程不存在 + MultipleProcessExist,//多个进程存在 + ThreadRuntimeError, //执行异常 + HandShakeError, //通讯握手失败 + ProtListenerError, //端口监听失败 + DeamonNotExist, //守护进程不存在 + SocketError//通讯失败 +} diff --git a/src/com/nis/nmsclient/thread/plugin/StartPluginRun.java b/src/com/nis/nmsclient/thread/plugin/StartPluginRun.java new file mode 100644 index 0000000..43ed9bc --- /dev/null +++ b/src/com/nis/nmsclient/thread/plugin/StartPluginRun.java @@ -0,0 +1,191 @@ +package com.nis.nmsclient.thread.plugin; + +import java.util.Date; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + +import com.nis.nmsclient.common.Common; +import com.nis.nmsclient.common.Contants; +import com.nis.nmsclient.config.DetecConfOper; +import com.nis.nmsclient.model.SetInfo; +import com.nis.nmsclient.thread.alarm.AlarmUtil; +import com.nis.nmsclient.util.ProcessUtil; +import com.nis.systeminfo.thread.NewPluginResultMerge; + +public class StartPluginRun implements Runnable { + static Logger logger = Logger.getLogger(StartPluginRun.class); + private String name; + private SetInfo setInfo; + + public StartPluginRun(SetInfo setInfo, String name) { + this.name = name; + this.setInfo = setInfo; + } + + public void run() { + Thread.currentThread().setName(name); + + logger.info("启动第三方插件程序开始!"); + if ("1".equals(setInfo.getCheckState()) + && "1".equals(setInfo.getCheckWay()) + && "1,2".contains(setInfo.getIsControlStart())) {// 有效,被动方式获取,Agent端启动 + Date startTime = null; + if (setInfo.getControlStartTime() != null && setInfo.getControlStartTime().longValue() != 0) { + startTime = new Date(setInfo.getControlStartTime()); + } else { + startTime = new Date(); + } + + /* + * 停止未启动的定时任务/周期任务 + */ + Common.stopPluginDetecFuture(setInfo.getId(), Thread.currentThread().getName()); + + /* + * 首先看进程设置的启动时间是否过时:如果过时,则查看进程是否存在,不存在启动;如果未过时,则定时启动 + */ + String cmd = DetecConfOper.getProcess(setInfo); + try { + /** + * 进程存在与否的判断标准: + * 1、先检查PID文件,取出PID,验证PID指定进程是否存在 + * PID文件不存在,或者PID文件中内容为空,或者取出的PID进程不存在,都认为不存在,进行下一步检查 + * 2、不存在再使用搜索关键字查找进程 + * 若未找出进程,不存在,若找出一个进程,正常存在,若找出多个进程,报警 + */ + + Object[] objArr = ProcessUtil.checkPidAndGetPid(setInfo.getProcessFile(), setInfo.getProcessSearchKeyCode()); + int isExistFlag = Integer.parseInt(objArr[0].toString()); + String pidInfo = objArr[1].toString(); + + if (isExistFlag == 0 || isExistFlag == 1) { // 进程不存在/存在一个进程 + if (isExistFlag == 1) {// 存在一个进程 + logger.info("三方监测进程”" + cmd + "“已存在,重启启动"); + ProcessUtil.killProcess(pidInfo); + } + + long delay = startTime.getTime() - System.currentTimeMillis(); + delay = Math.max(delay, 0); + + ScheduledFuture future = null; + if ("1".equals(setInfo.getIsControlStart())) { + future = Common.scheduled.schedule(new ExecProcess(), delay, TimeUnit.MILLISECONDS); + } else if ("2".equals(setInfo.getIsControlStart())) { + long period = setInfo.getCheckGap() * 60 * 1000; + future = Common.scheduled.scheduleAtFixedRate(new ExecProcess2(), delay, period, TimeUnit.MILLISECONDS); + } + + Common.putPluginDetecFuture(setInfo.getId(), future); + logger.info("三方监测程序已加入定时器定时启动"); + + } else { // 找到多个进程,告警 +// String alarmMsg = "启动三方监测:" + pidInfo; + String alarmMsg = "i18n_client.StartPluginRun.startupDetecate_n81i:" + pidInfo; + AlarmUtil.sendAlarmMsg(setInfo.getId(), setInfo + .getCheckTypeName(), setInfo.getProcessIden(), + new Date(), new Date(), 1, + Contants.DETECTION_STATUS_FAILURE, alarmMsg); + } + + } catch (Exception e) { + logger.error("Start the three party monitoring exception. Please check whether the process execution file and the PID file are set correctly:" + cmd, e); + } + } + logger.info("启动第三方插件程序结束!"); + }// run end + + class ExecProcess implements Runnable { + public void run() { + Thread.currentThread().setName(name); + String cmd = DetecConfOper.getProcess(setInfo); + try { + // 启动 + ProcessUtil.runExec(cmd, null, null, null); + + // 检查PID + Object[] objArr = ProcessUtil.checkPidAndGetPid(setInfo.getProcessFile(), setInfo.getProcessSearchKeyCode()); + int isExistFlag = Integer.parseInt(objArr[0].toString()); + String pidInfo = objArr[1].toString(); + + if (isExistFlag == 1) {// 存在, 一个进程 + logger.info("三方监测程序“" + cmd + "“启动成功"); + } else { // 进程不存在 或 找到多个进程,告警 + String alarmMsg = null; + if (isExistFlag == 0) {// 进程不存在 +// alarmMsg = "三方监测程序启动失败,请检查进程启动文件“" + cmd + "”是否设置正确"; + alarmMsg = "i18n_client.StartPluginRun.startupDetecateErr1_n81i “" + cmd + "” i18n_client.StartPluginRun.startupDetecateErr1.isTrue_n81i"; + } else {// 找到多个进程 +// alarmMsg = "启动三方监测:" + pidInfo; + alarmMsg = "i18n_client.StartPluginRun.startupDetecate_n81i:" + pidInfo; + } + AlarmUtil.sendAlarmMsg(setInfo.getId(), setInfo + .getCheckTypeName(), setInfo.getProcessIden(), + new Date(), new Date(), 1, + Contants.DETECTION_STATUS_FAILURE, alarmMsg); + } + + } catch (Exception e) { + logger.error("Start the three party monitoring exception. Please check whether the process execution file and the PID file are set correctly:" + cmd, e); + } + } + } + + class ExecProcess2 implements Runnable { + public void run() { + + Thread.currentThread().setName(name); + // 三方监测脚本执行命令不存在,获取脚本命令及关键词 + // 因脚本下发与配置下发不同步,需要在执行任务中多次获取执行命令 + String cmd = Common.generateCommandAndKeyword(setInfo); + try { + boolean executeStatus = true; + + // 脚本执行前,清理临时数据目录 + new NewPluginResultMerge().clearTmpFile(setInfo); + + if (StringUtils.isBlank(cmd)) { + // 三方监测脚本执行命令不存在,当前时间NC上无监测脚本 + logger.info("三方监测程序启动失败,监测脚本下发未完成!"); +// String alarmMsg = "启动三方监测异常,监测脚本下发未完成!"; + String alarmMsg = "i18n_client.StartPluginRun.startupDetecateErr2_n81i"; + AlarmUtil.sendAlarmMsg(setInfo.getId(), + setInfo.getCheckTypeName(), + setInfo.getProcessIden(), new Date(), new Date(), + 1, Contants.DETECTION_STATUS_FAILURE, alarmMsg); + executeStatus = false; + + } else { + // 启动脚本 + String msg = ProcessUtil.runExec(cmd, null, null, null); + + if (StringUtils.isBlank(msg)) { // 执行成功 + logger.info("三方监测程序“" + cmd + "”执行成功"); + + } else { // 执行失败,返回错误信息 + logger.error("Three party monitoring procedure“" + cmd + "”erroneous execution:" + msg); +// String alarmMsg = "启动三方监测异常,监测脚本执行错误!"; + String alarmMsg = "i18n_client.StartPluginRun.startupDetecateErr3_n81i"; + AlarmUtil.sendAlarmMsg(setInfo.getId(), + setInfo.getCheckTypeName(), + setInfo.getProcessIden(), new Date(), + new Date(), 1, + Contants.DETECTION_STATUS_FAILURE, alarmMsg); + executeStatus = false; + } + } + + // 针对执行合并临时文件(ProcessUtil.runExec为同步执行,合并临时文件前已完成脚本执行过程) + if(executeStatus) { + new NewPluginResultMerge().merge(setInfo); + } + + } catch (Exception e) { + logger.error("Start the three party monitoring exception. Please check whether the process execution file and the PID file are set correctly:" + cmd, e); + } + } + } + +} diff --git a/src/com/nis/nmsclient/thread/socket/CommonSocket.java b/src/com/nis/nmsclient/thread/socket/CommonSocket.java new file mode 100644 index 0000000..8248f32 --- /dev/null +++ b/src/com/nis/nmsclient/thread/socket/CommonSocket.java @@ -0,0 +1,1199 @@ +package com.nis.nmsclient.thread.socket; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.net.InetAddress; +import java.net.Socket; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.LinkedList; +import java.util.List; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + +import com.nis.nmsclient.common.Contants; +import com.nis.nmsclient.util.FileUtil; +import com.nis.nmsclient.util.MD5Util; +import com.nis.nmsclient.util.Utils; +import com.nis.nmsclient.util.file.BufferedRandomAccessFile; +import com.socket.utils.FileComment; + +public class CommonSocket{ + static Logger logger = Logger.getLogger(CommonSocket.class); + protected static final String TEMP_SUFFIX = ".tp"; + //缓存字节长度 + protected static final int BUFF_SIZE = 1024; + public static final String SUCCESS = "success"; + public static final String FAIL = "fail"; + public static final String END = "end"; + /** + * 与Server握手请求 + */ + public static final String REQ_HAND_SHAKE = "char:handshake"; + /** + * 获取本机标志UUID请求 + */ + public static final String REQ_LOCAL_UUID = "char:uuid"; + /** + * 发送本机变更信息请求 + */ + public static final String REQ_LOCAL_CHANGE = "char:agentChange"; + /** + * 初始化配置请求 + */ + public static final String REQ_INIT_CONFIG = "char:init"; + /** + * 初始化任务请求 + */ + public static final String REQ_INIT_TASK = "char:initTask"; + /** + * 主动告警请求 + */ + public static final String REQ_ALARM = "char:alarm"; + /** + * 获取Server端系统时间请求 + */ + public static final String REQ_SERVER_SYSTEMDATE = "char:systemdate"; + /** + * Server升级请求 + */ + public static final String REQ_SERVER_UPGRADE = "char:upgradeServer"; + /** + * NC向DC发送错误信息 + */ + public static final String REQ_ERROR_INFO = "char:ncErrorInfo"; + // ========== 现由DC主动获取数据,以下命令暂留 + /** + * 批量上传数据文件请求 + */ + public static final String REQ_UPLOAD_DATAS ="byte:datas"; + /** + * 回传文件请求 + */ + public static final String REQ_TASK_RETURNFILE = "byte:taskReturn"; + // ========== 现由DC主动获取数据,以上命令暂留 + /** + * 发送任务结果请求【数据收集方式改为DC主动后,此请求只在NC启动时发送所有任务结果使用】 + */ + public static final String REQ_TASK_RESULT = "char:taskResult"; + /** + * 上传回传文件、任务结果文件、数据文件的打包文件请求【数据收集方式改为DC主动后,此请求只在NC启动时发送所有任务结果使用】 + */ + public static final String REQ_BP_UPLOAD_FIFE = "byte:bpUploadFile"; + //bpUploadFile的子命令类型 + public static final String BP_TYPE_TASK_RESULT = "taskresult"; + public static final String BP_TYPE_TASK_RETURN = "taskreturn"; + public static final String BP_TYPE_DETECT_DATA = "detectdata"; + /** + * 交换证书通信命令 + */ + public static final String REQ_CERT = "byte:cert"; + /** + * 更新监测设置信息通信命令 + */ + public static final String SERVER_UPDATE_CONFIG = "char:updateConfig"; + /** + * 下发第三方监测脚本命令 + */ + public static final String SEND_PLUGIN_SCRIPT_FILE = "char:sendPluginScriptFile"; + /** + * NC端是否报主动告警 变更 + */ + public static final String ACTIVE_ALARM_START_ALERT = "char:isActiveAlarmStart"; + /** + * 文件推送通信命令 + */ + public static final String SERVER_FILE_PUSH = "byte:filePush"; + /** + * 升级通信命令 + */ + public static final String SERVER_UPGRADE = "byte:upgrade"; + /** + * 下发任务通信命令 + */ + public static final String SERVER_TASK = "char:task"; + /** + * 任务撤消命令 + */ + public static final String SERVER_TASK_CANCEL = "char:taskCancel"; + /** + * DC主动向NC再次获取任务结果 + */ + public static final String SERVER_GET_TASKRESULT = "char:collectNonRltTaskResult"; + /** + * DC主动向NC收集监测数据 + */ + public static final String SERVER_COLLECT_DATA = "byte:collectData"; + //收集数据,Agent发送的类型 + public static final String DATA_TYPE_ZIP_DETECT = "zipDetectData";//监测数据zip + public static final String DATA_TYPE_CSV_DETECT = "csvDetectData";//批量上传csv监测数据 + public static final String DATA_TYPE_ZIP_TASKRESULT = "zipTaskResult";//任务结果zip + public static final String DATA_TYPE_OBJ_TASKRESULT = "objTaskResult";//批量上传任务结果obj + public static final String DATA_TYPE_ZIP_TASKRETURN = "zipTaskReturn";//任务回传文件zip + public static final String DATA_TYPE_FILE_TASKETURN = "fileTaskReturn";//单个任务回传文件 + + protected Socket socket = null; + protected OutputStream out = null; + protected InputStream in = null; + + public CommonSocket() { + super(); + } + + public CommonSocket(Socket client) throws Exception { + socket = client; + out = socket.getOutputStream(); + in = socket.getInputStream(); + } + + /** + * 发送消息,以字符形式,发送一行信息 + **/ + public boolean sendMessageByChar(String msg) throws Exception { + logger.debug("sendMessageByChar---" + msg); + PrintWriter pw = new PrintWriter(new OutputStreamWriter(out, + Contants.charset)); + pw.println(msg); + pw.flush(); + + return true; + } + + + /** + * 接收信息,以字符形式,接收一行信息 + * + */ + public String receiveMessageByChar() throws Exception { + BufferedReader br = new BufferedReader(new InputStreamReader(in, + Contants.charset)); + String str = br.readLine(); + logger.debug("receiveMessageByChar---" + str); + return str; + } + + /** + * 发送单个文件 + **/ + public boolean sendFileByByte(File file) throws Exception { + ObjectOutputStream oos = null; + FileInputStream fis = null; + try { + //发送文件大小和文件名 + oos = new ObjectOutputStream(out); + String[] strArr = new String[]{ + file.length() + "", file.getName() + }; + oos.writeObject(strArr); + //发送文件内容 + byte[] buff = new byte[BUFF_SIZE]; + int len = 0; + fis = new FileInputStream(file); + while ((len = fis.read(buff)) != -1) { + //将读取的内容写入文件 + out.write(buff, 0, len); + } + out.flush(); + } catch (Exception e) { + logger.error("Single file sending failure"); + throw e; + } finally{ + if(fis!=null){ + try { + fis.close(); + } catch (IOException e) { + logger.error(Utils.printExceptionStack(e)); + } + } + } + + return true; + } + + /** + * 接收单个文件 + * + */ + public boolean receiveFileByByte(String filePath) throws Exception { + ObjectInputStream ois = null; + FileOutputStream fos = null; + try { + + ois = new ObjectInputStream(in); + String[] strArr = (String[])ois.readObject(); + //接收文件大小 + long fileSize = Long.parseLong(strArr[0]); + //接收文件名 + String fileName = strArr[1]; + + //接收文件内容 + byte[] buff = new byte[BUFF_SIZE]; + fos = new FileOutputStream(filePath + File.separator + fileName); + int nRead = 0; + + //单个文件循环读取 + while ((nRead = in.read(buff, 0, (int)(BUFF_SIZE 0) { + fos.write(buff,0,nRead); + fos.flush(); + fileSize -= nRead; + if(fileSize<=0){ + break; + } + } + fos.close(); + } catch (Exception e) { + logger.error("Single file receiving failure"); + throw e; + } finally { + try { + if (fos != null) { + fos.close(); + } + } catch (IOException e) { + logger.error(Utils.printExceptionStack(e)); + } + + } + + return true; + + } + + /** + * 批量上传文件 + * @param dir 本地文件集合根目录绝对路径 + * @param fileList 上传的文件列表 + */ + public void sendFileByBath(String dir, List fileList) throws Exception { + ObjectOutputStream oos = null; + FileInputStream fis = null; + + try { + // 第一步发送本地根目录地址(用于地址截取)保证fileList的目录结构完整性 + this.sendMessageByChar(dir); + String result = this.receiveMessageByChar(); + logger.debug("根目录地址发送状态: " + result); + // 第二步 用ObjectOutputStream工具类 发送file对象信息 用于文件名,文件目录,文件大小的获取 + oos = new ObjectOutputStream(out); + List fileStrList = new ArrayList(); + if(fileList!=null && fileList.size()>0){ + for (File f : fileList) { + if (f.exists()) { + String[] tmpArr = new String[] { f.getAbsolutePath(), + f.length() + "" }; + fileStrList.add(tmpArr); + } else { + logger.warn("File:>" + f.getAbsolutePath() + + " do not exist, can not send"); + } + } + oos.writeObject(fileStrList); + // 第三部,发送文件 + byte[] buff = new byte[BUFF_SIZE]; + int len = 0; + // 循环上传文件 + for (File file : fileList) { + logger.debug("--sendFileByBath---" + file.getName() + "---length=" + file.length()); + fis = new FileInputStream(file); + while ((len = fis.read(buff)) != -1) {// 将读取的内容输出流 + out.write(buff, 0, len); + } + out.flush(); + fis.close(); + fis = null; + } + } + logger.debug("批量发送文件个数:" + (fileList==null ? 0 : fileList.size())); + } catch (Exception e) { + throw e; + } finally { + try { + if (fis != null) { + fis.close(); + fis = null; + } + } catch (IOException e) { + } + } + } + + /** + * 批量接收文件 + * @param newDir + */ + public boolean receiveFileByBath(String newDir) throws Exception { + ObjectInputStream ois = null; + FileOutputStream fos = null; + try { + //获取集合文件路径 + String oldDir = this.receiveMessageByChar(); + //logger.info("旧上传文件集合根目录: " + oldDir); + this.sendMessageByChar("success"); + ois = new ObjectInputStream(in); + List fileList = (List)ois.readObject(); + if(fileList != null && fileList.size()>0){ + for(String[] arr : fileList){ + String newUrl = arr[0].replace(oldDir, newDir);//新路径 + newUrl = newUrl.replaceAll("\\\\", "/"); + int fileLength = Integer.parseInt(arr[1]); //大小 + File newFile = new File(newUrl); + if(newFile.exists()){ + FileUtil.delDir(newFile); + logger.debug("receiveFileByBath delete file---" + newFile.getAbsolutePath()); + } + if(!newFile.getParentFile().exists()){ + newFile.getParentFile().mkdirs(); + } + fos = new FileOutputStream(newUrl+TEMP_SUFFIX); + + int nRead = 0; + byte[] buff = new byte[BUFF_SIZE]; + //单个文件循环读取 + while ((nRead = in.read(buff, 0, (int)(BUFF_SIZE 0) { + fos.write(buff,0,nRead); + fos.flush(); + fileLength -= nRead; + if(fileLength<=0){ + break; + } + } + fos.close(); + fos = null; + File newFile2 = new File(newUrl+TEMP_SUFFIX); + //newFile2.renameTo(newFile); + FileUtils.copyFile(newFile2, newFile);//将临时文件名改为正式文件名,即去掉.tp后缀 + newFile2.delete();// 将临时文件删除 + } + } + logger.debug("批量接收文件个数:" + (fileList==null ? 0 : fileList.size())); + } catch (Exception e) { + throw e; + }finally{ + if(fos!=null){ + try { + fos.close(); + fos = null; + } catch (IOException e) { + } + } + } + + return true; + + } + + /** + * 批量上传文件, 并传入文件的Md5值 + * @param fileList 上传的文件列表 + */ + protected void sendFileWithMd5ByBath(List fileCommentsList) throws IOException { + ObjectOutputStream oos = null; + FileInputStream fis = null; + + try { + // 第一步 用ObjectOutputStream工具类 发送file对象信息 用于文件名,文件目录,文件大小的获取 + oos = new ObjectOutputStream(out); + List fileList = new LinkedList(); + List fileStrList = new ArrayList(); + for(String[] fileComments : fileCommentsList){ + File file = new File(fileComments[0]); + if(file.exists()){ + String[] tmpArr = new String[]{ + file.getName(), file.length() + "",fileComments[1] + }; + fileList.add(file); + fileStrList.add(tmpArr); + }else { + logger.warn("File:>"+file.getAbsolutePath()+" do not exist, can not send"); + } + } + oos.writeObject(fileStrList); + // 第三部,发送文件 + byte[] buff = new byte[BUFF_SIZE]; + int len = 0; + // 循环上传文件 + for (File file : fileList) { + fis = new FileInputStream(file); + while ((len = fis.read(buff)) != -1) {// 将读取的内容输出流 + out.write(buff, 0, len); + } + out.flush(); + fis.close(); + fis = null; + } + logger.debug("批量发送文件结束,共 "+(fileList==null ? 0 : fileList.size())+ "个文件"); + } catch (IOException e) { + logger.error("Batch file failed!"); + throw new IOException(e); + } finally { + try { + if (fis != null) { + fis.close(); + fis = null; + } + } catch (IOException e) { + } + } + } + + /** + * 批量接收文件, 使用Md5校验文件是否完整 + * @param newDir + */ + public boolean receiveFileWithMd5ByBath(String newDir) throws IOException { + boolean flag = true; + ObjectInputStream ois = null; + FileOutputStream fos = null; + try { + ois = new ObjectInputStream(in); + List fileList = (List)ois.readObject(); + if(fileList != null && fileList.size()>0){ + int sucessCnt = 0; + int failCnt = 0; + for(int i=0; i 0) { + fos.write(buff,0,nRead); + fos.flush(); + fileLength -= nRead; + if(fileLength<=0){ + break; + } + } + fos.close(); + fos = null; + File newFile2 = new File(newUrl+TEMP_SUFFIX); + if (md5Val != null + && md5Val + .equals(MD5Util.getFileMD5String(newFile2))) { + logger.debug("接收文件" + (i+1) + "“" + newFile.getAbsolutePath() + "”完整"); + //newFile2.renameTo(newFile); + FileUtils.copyFile(newFile2, newFile);//将临时文件名改为正式文件名,即去掉.tp后缀 + newFile2.delete();// 将临时文件删除 + sucessCnt ++ ; + } else { + logger.debug("接收文件" + (i+1) + "“" + newFile.getAbsolutePath() + "”不完整,失败"); + failCnt ++ ; + } + } + logger.info("批理接收文件个数:" + fileList.size() + ", 成功:" + sucessCnt + ", 失败:" + failCnt); + if(failCnt > 0) { + flag = false; + } + }else{ + logger.info("批量接收文件列表为空"); + } + } catch (Exception e) { + logger.error("Batch file failure"); + throw new IOException(e); + }finally{ + if(fos!=null){ + try { + fos.close(); + fos = null; + } catch (IOException e) { + } + } + } + + return flag; + } + + /** + * 断点续传 发送方法 + * @time Mar 2, 2012-2:30:16 PM + * @param filePath + */ + protected boolean bpSendFile (String filePath) throws Exception { + File file = new File(filePath); + + //发送长度 end + this.sendMessageByChar(file.length()+""); + + String msg = this.receiveMessageByChar(); + long start = Long.parseLong(msg); + long end = file.length(); + logger.debug("start "+start); + logger.debug("end "+end); + bpSendFile(filePath, start, end); + + return true; + } + + /** + * 断点续传 接收方法 + * @time Mar 2, 2012-2:30:16 PM + * @param filePath + * @param start + * @param end + */ + protected int bpReceiveFile (String filePath) throws Exception { + File file = new File(filePath); + if(!file.exists()){ + file = new File(filePath+TEMP_SUFFIX); + } + String msg = this.receiveMessageByChar(); + long start = file.length(); + long end = Long.parseLong(msg); + this.sendMessageByChar(start+""); + + logger.debug("start "+start); + logger.debug("end "+end); + bpReceiveFile(file.getAbsolutePath(), start, end); + + //file.renameTo(new File(filePath)); + FileUtils.copyFile(file, new File(filePath));//将临时文件名改为正式文件名,即去掉.tp后缀 + file.delete();// 将临时文件删除 + + logger.debug("bpReceiveFile sucess"); + return 0; + } + + /** + * 断点续传 发送方法 + * @time Mar 2, 2012-2:30:16 PM + * @param filePath + * @param start + * @param end + */ + protected void bpSendFile (String filePath,long start,long end) throws Exception { + if (start == end) { + return; + } + BufferedRandomAccessFile braf = null; + try { + File file = new File(filePath); + + //- 不存在,终止; 存在则继续 + if(!file.exists()){ + this.sendMessageByChar(FAIL); + return ; + }else { + this.sendMessageByChar(SUCCESS); + } + + String msg = this.receiveMessageByChar(); + logger.debug("Recive: " + msg); + + //- BufferedRandomAccessFile 读取指定位置的文件字节数组,写入输出通讯 + byte[] b = new byte[BUFF_SIZE]; + braf = new BufferedRandomAccessFile(file,"r"); + braf.seek(start); + int nRead; + while ((nRead = braf.read(b, 0, BUFF_SIZE)) > 0) { + + out.write(b, 0, nRead); + start += nRead; + + //-- 读取完成 跳出 + if(start==end){break;} + + } + + }catch (Exception e) { + throw e; + }finally{ + try { + //- 关闭 随机访问文件对象(关闭流) + if(braf!= null){braf.close();} + } catch (IOException e) { + logger.error(Utils.printExceptionStack(e)); + } + + } + } + /** + * 断点续传 接收方法 + * @time Mar 2, 2012-2:30:16 PM + * @param filePath + * @param start + * @param end + */ + protected void bpReceiveFile (String filePath,long start,long end) throws Exception { + if(StringUtils.isEmpty(filePath)){ + return; + } + if (start == end) { + return; + } + BufferedRandomAccessFile raf = null; + try { + File file = new File(filePath); + + //- 文件路径不存在 则创建 + if (!file.getParentFile().exists()) { + file.getParentFile().mkdirs(); + } + + //- 文件不存在 则创建 + if (!file.exists()) { + file.createNewFile(); + } + + //- 接收发送端 发送数据准备 确认信息 + String msg = this.receiveMessageByChar(); + + if (FAIL.equals(msg)) { //结束操作 + return; + } else { + this.sendMessageByChar(SUCCESS); // 通知发送端 接收数据准备完成 确认信息 + } + + // 将通信中读出的数据 写入文件指定位置 + byte[] b = new byte[BUFF_SIZE]; + raf = new BufferedRandomAccessFile(file, "rw"); + raf.seek(start); + int nRead; + + while ((nRead = in.read(b, 0, BUFF_SIZE)) > 0) { + raf.write(b, 0, nRead); + start += nRead; + + if (start == end) { //写完跳出 + break; + } + } + } catch (Exception e) { + throw e; + }finally{ + try { + //- 关闭 随机访问文件对象(关闭流) + if(raf!= null){raf.close();} + } catch (IOException e) { + logger.error(Utils.printExceptionStack(e)); + } + } + } + + /** + * 断点续传 批量上传文件 + * @param fileList 上传的文件列表 + * @param dir 本地文件集合根目录绝对路径 + */ + protected void bpSendFileByBath(List fileList,String dir) throws Exception { + BufferedRandomAccessFile oReadFile = null; + + try { + // 第一步发送本地根目录地址(用于地址截取)保证fileList的目录结构完整性 + this.sendMessageByChar("abs:"+(dir==null?"":dir)); + String result = this.receiveMessageByChar(); + logger.debug("根目录路径通信状态: " + result); + // 第二步 用ObjectOutputStream工具类 发送file对象信息 用于文件名,文件目录,文件大小的获取 + + //原文件文件名 和 大小(即end长度) + List sourceFileList = new ArrayList(); + for(File f : fileList){ + String[] tmpArr = new String[]{ + f.getAbsolutePath(),0+"",f.length() + "" + }; + sourceFileList.add(tmpArr); + } + + logger.debug("发送信息: " + Arrays.toString(sourceFileList.toArray())); + this.sendObject(sourceFileList); + + //得到需要下载的文件信息 + List sendFileList = (List)receiveObject(); + + // 第三部,发送文件 + byte[] buff = new byte[BUFF_SIZE]; + + // 循环上传文件 + for (String[] sendFile: sendFileList) { + long start = Long.parseLong(sendFile[1]); + long end = Long.parseLong(sendFile[2]); + if(start >= end){ + continue; + } + File file = new File(sendFile[0]); + oReadFile = new BufferedRandomAccessFile(file,"r"); + + // 定位文件指针到nPos位置 + oReadFile.seek(start); //从0开始 + int nRead; + + // 从输入流中读入字节流,然后写到文件中 + while ((nRead = oReadFile.read(buff, 0, BUFF_SIZE)) > 0) { + + out.write(buff, 0, nRead); + start += nRead; //调整为从1开始 + if(start >= end){ + break; + } + + } + oReadFile.close(); + oReadFile = null; + } + logger.debug("多文件上传结束,共 "+(fileList==null ? 0 : fileList.size())+ "个文件"); + } catch (Exception e) { + throw e; + } finally { + try { + if (oReadFile != null) { + oReadFile.close(); + oReadFile = null; + } + } catch (IOException e) { + logger.error(Utils.printExceptionStack(e)); + } + } + } + + /** + * 断点续传 批量接收文件 + * @param newDir + */ + protected void bpReceiveFileByBath(String newDir) throws Exception { + + BufferedRandomAccessFile oSavedFile = null; + try { + //获取集合文件路径 + String oldDir = this.receiveMessageByChar(); + int headLength = "abs:".length(); + oldDir = ((StringUtils.isNotEmpty(oldDir) + && oldDir.length()>=headLength) + ?oldDir.substring(headLength,oldDir.length()) + :oldDir); + if(StringUtils.isEmpty(oldDir)){ + logger.debug("远程 目录根路径为空 接收文件不保留目录格式 统一存放到本地目录:》"+newDir); + }else{ + logger.debug("根目录 记录: " + oldDir+" VS "+newDir); + } + this.sendMessageByChar(SUCCESS); + + List remoteFileList = (List)receiveObject(); + List receiveFileList = new LinkedList(); + byte[] buff = new byte[BUFF_SIZE]; + if(remoteFileList != null && remoteFileList.size()>0){ + for(String[] arr : remoteFileList){ + String newUrl = null; + if(StringUtils.isEmpty(oldDir)){ + newUrl = newDir+(new File(arr[0].replaceAll("\\\\", "/")).getName()); + }else{ + newUrl = arr[0].replace(oldDir, newDir);//新路径 + newUrl = newUrl.replaceAll("\\\\", "/"); + } + + File newFile = new File(newUrl); + + //该文件已存在 + if(newFile.exists()){ + continue; + } + + newFile = new File(newUrl+TEMP_SUFFIX); + arr[1] = newFile.length()+""; + receiveFileList.add(arr); + } + } + this.sendObject(receiveFileList); + + if(receiveFileList != null && receiveFileList.size()>0){ + for(String[] arr : receiveFileList){ + String newUrl = null; + if(StringUtils.isEmpty(oldDir)){ + newUrl = newDir+(new File(arr[0].replaceAll("\\\\", "/")).getName()); + }else{ + newUrl = arr[0].replace(oldDir, newDir);//新路径 + newUrl = newUrl.replaceAll("\\\\", "/"); + } + + File newFile = new File(newUrl+TEMP_SUFFIX); + + if(!newFile.getParentFile().exists()){ + newFile.getParentFile().mkdirs(); + } + + if(!newFile.exists()){ + newFile.createNewFile(); + } + + int start = Integer.parseInt(arr[1]); // 起始 + int end = Integer.parseInt(arr[2]); // 结束 + if(start 0) { + oSavedFile.write(buff,0,nRead); + end -= nRead; + if(end<=0){ + break rfile; + } + } + oSavedFile.close(); + oSavedFile = null; + } +// newFile.renameTo(new File(newUrl)); //将临时文件名改为正式文件名,即去掉.tp后缀 + FileUtils.copyFile(newFile, new File(newUrl)); //将临时文件名改为正式文件名,即去掉.tp后缀 + newFile.delete(); + } + } + logger.debug("多文件接收结束,共 "+(remoteFileList==null ? 0 : remoteFileList.size())+ "个文件"); +// } catch (IOException e) { +// logger.error("",e); +// } catch (ClassNotFoundException e) { +// logger.error("",e); + }finally{ + if(oSavedFile!=null){ +// try { + oSavedFile.close(); + oSavedFile = null; +// } catch (IOException e) { +// logger.error("",e); +// } + } + } + } + + /** + * 断点续传 批量上传文件, 并传入文件的Md5值 + * @param fileList 上传的文件列表 + * @param dir 本地文件集合根目录绝对路径 + */ + protected void bpSendFileByBathMD5(List fileCommentsList) throws Exception { + BufferedRandomAccessFile oReadFile = null; + + try { + //原文件文件名 和 大小(即end长度) + List sourceFileList = new ArrayList(); + if(fileCommentsList !=null && fileCommentsList.size()!=0){ + for(FileComment fileComment : fileCommentsList){ + File f = new File(fileComment.getFileName()); + if(!f.exists()){ + sourceFileList.add(new FileComment(f.getAbsolutePath(),0,-1,fileComment.getMd5Val())); + }else { + String md5Val = StringUtils.isEmpty(fileComment.getMd5Val())?MD5Util.getFileMD5String(f):fileComment.getMd5Val(); + sourceFileList.add(new FileComment(f.getAbsolutePath(),0,f.length(),md5Val)); + } + } + } + + logger.debug("发送信息: " + Arrays.toString(sourceFileList.toArray())); + this.sendObject(sourceFileList); + + //得到需要下载的文件信息 + List sendFileList = (List)receiveObject(); + + // 第三部,发送文件 + byte[] buff = new byte[BUFF_SIZE]; + + // 循环上传文件 + for (FileComment sendFile: sendFileList) { + long start = sendFile.getStart(); + long end = sendFile.getEnd(); + if(start >= end){ + continue; + } + File file = new File(sendFile.getFileName()); + oReadFile = new BufferedRandomAccessFile(file,"r"); + + // 定位文件指针到nPos位置 + oReadFile.seek(start); //从0开始 + int nRead; + + // 从输入流中读入字节流,然后写到文件中 + while ((nRead = oReadFile.read(buff, 0, BUFF_SIZE)) > 0) { + + out.write(buff, 0, nRead); + start += nRead; //调整为从1开始 + if(start >= end){ + break; + } + + } + oReadFile.close(); + oReadFile = null; + } + logger.debug("多文件上传结束,共 "+(sendFileList==null ? 0 : sendFileList.size())+ "个文件"); + } catch (Exception e) { + throw e; + } finally { + try { + if (oReadFile != null) { + oReadFile.close(); + oReadFile = null; + } + } catch (IOException e) { + logger.error(Utils.printExceptionStack(e)); + } + } + } + + + /** + * 断点续传 批量接收文件, 使用Md5校验文件是否完整 + * @param newDir + */ + public int bpReceiveFileByBathMd5(String newDir) throws Exception{ + if(newDir!=null){ + newDir += File.separator; + } + int rFlag = 0; //0 OK -1 MD5 ERROR -2 Function ERROR -3 文件不存在 + BufferedRandomAccessFile oSavedFile = null; //有缓存的 随机文件IO对象 + try { + + List remoteFileList = (List)receiveObject(); //接收可接收的文件信息 string[]{fileName,start,end,MD5} + List receiveFileList = new LinkedList(); //需要续传的文件及其索引信息 string[]{fileName,start,end,MD5} + byte[] buff = new byte[BUFF_SIZE]; //缓存 大小 + + //- 检查实际接收文件大小 + if(remoteFileList != null && remoteFileList.size()>0){ + for(FileComment arr : remoteFileList){ + //String newUrl = newDir+removeTimeTagFileName(new File(arr.getFileName()).getName(),null); + String filePath = arr.getFileName().replaceAll("\\\\", "/"); + String fileName = filePath.substring(filePath.lastIndexOf("/")+1, filePath.length()); + String newUrl = newDir+removeTimeTagFileName(fileName,null); + + File newFile = new File(newUrl); + + //-- 已接收完成 + if(newFile.exists()){ + // continue; + // 2013-1-6 jzz 如果接收完成也比较MD5值,主要是针对再次执行任务,直接拷来的文件 + //-- MD5为空 无需校验 + if(StringUtils.isEmpty(arr.getMd5Val())){ + continue; + } + //-- MD5相等, 接收完成 + if(arr.getMd5Val().equals(MD5Util.getFileMD5String(newFile))){ + logger.debug("1--" + newFile.getAbsolutePath()+" MD5值校验一致"); + continue; + } else {//-- MD5不相等,则删除该文件,下面重新接收 + FileUtil.delDir(newFile); + logger.debug("1--bpReceiveFileByBathMd5 delete file ---" + newFile.getAbsolutePath()); + logger.debug("1--" + newFile.getAbsolutePath()+" MD5值校验不一致"); + } + // 2013-1-6 jzz 修改结束 + } + + //-- 续传文件及起始长度 + newFile = new File(newUrl+TEMP_SUFFIX); + arr.setStart(newFile.length()); + receiveFileList.add(arr); + } + } + this.sendObject(receiveFileList); + + //- 接收文件 + if(receiveFileList != null && receiveFileList.size()>0){ + for(FileComment arr : receiveFileList){ + //String newUrl = newDir+removeTimeTagFileName(new File(arr.getFileName()).getName(),null); + String filePath = arr.getFileName().replaceAll("\\\\", "/"); + String fileName = filePath.substring(filePath.lastIndexOf("/")+1, filePath.length()); + String newUrl = newDir+removeTimeTagFileName(fileName,null); + + File newFile = new File(newUrl+TEMP_SUFFIX); + + if(!newFile.getParentFile().exists()){ + newFile.getParentFile().mkdirs(); + } + + //创建空文件 + if (!newFile.exists()) { + newFile.createNewFile(); + } + + long start = arr.getStart(); // 起始 + long end = arr.getEnd(); // 结束 + if(end == -1){ + return -3; + } + + if(start 0) { + oSavedFile.write(buff,0,nRead); + end -= nRead; + if(end<=0){ + break rfile; + } + } + oSavedFile.close(); + oSavedFile = null; + } + //newFile.renameTo(new File(newUrl)); + FileUtils.copyFile(newFile, new File(newUrl));//将临时文件名改为正式文件名,即去掉.tp后缀 + newFile.delete();// 将临时文件删除 + logger.debug(newFile.getAbsolutePath()+" 下载完成!"); + + //-- MD5为空 无需校验 + if(StringUtils.isEmpty(arr.getMd5Val())){ + continue; + } + + File newFile2 = new File(newUrl); + //-- MD5不相等,则删除该文件 返回-1 + if(!arr.getMd5Val().equals(MD5Util.getFileMD5String(newFile2))){ + //newFile.delete_bak(); + //使用删除文件公共方法 + FileUtil.delDir(newFile); + logger.debug("bpReceiveFileByBathMd5 delete file ---" + newFile.getAbsolutePath()); + //FileUtil.checkParentDirExist(newFile); + logger.debug(newFile.getAbsolutePath()+" MD5值校验不一致"); + return -1; + } else {//-- MD5相等 + logger.debug(newFile.getAbsolutePath()+" MD5值校验一致"); + } + } + } + logger.debug("多文件接收结束,共 "+(remoteFileList==null ? 0 : remoteFileList.size())+ "个文件"); + return rFlag; + } catch (Exception e) { + //return -2; + throw e; + }finally{ + if(oSavedFile!=null){ + try { + oSavedFile.close(); + oSavedFile = null; + } catch (IOException e) { + logger.error(Utils.printExceptionStack(e)); + } + } + } + } + + /** + * Object 形式 发送信息 + */ + protected void sendObject(Object object) throws Exception { + ObjectOutputStream oos = new ObjectOutputStream(out); + oos.writeObject(object); + oos.flush(); + } + + /** + * Object 形式 接收信息 + */ + protected Object receiveObject() throws Exception { + ObjectInputStream ois = new ObjectInputStream(in); + return ois.readObject(); + } + + /** + * 关闭通讯 + */ + public void close() { + try { + if(out!=null){ + out.close(); + out = null; + } + if(in!=null){ + in.close(); + in = null; + } + if(socket!=null && socket.isConnected()){ + socket.close(); + socket = null; + } + } catch (Exception e) { + logger.error(Utils.printExceptionStack(e)); + } + } + + /** + * 删除addTimeTagForFileName()方法 所添加的时间戳 + * @time Mar 12, 2012-3:36:16 PM + * @param fileName + * @return + */ + public static String removeTimeTagFileName(String fileName, String taskId) { + + if (StringUtils.isNotBlank(fileName) && fileName.contains("_")) { + + String timeTag = fileName.substring(fileName.lastIndexOf("_"), + fileName.lastIndexOf(".")==-1?fileName.length():fileName.lastIndexOf(".")); //针对无后缀名文件,时间戳截取校验 + fileName = fileName.replace(timeTag, ""); + + if(taskId!=null){ + fileName = fileName.replace("_" + taskId, ""); + } + + } + + return fileName; + + } + + /** + * 上传文件时,判断该文件是否已存在,如存在,则在后面加入时间戳 + * + * @param fileName + * 单纯的文件名 + * @param taskId 标识ID + * @return + * @throws UnknownHostException + */ + public static String addTimeTagForFileName(String fileName, String taskId, boolean isFile){ + + try + { + Calendar calendar = new GregorianCalendar(); + long timestamp = calendar.getTimeInMillis(); + + // 文件后缀 + String fielType = ""; + + if (isFile) {// 只是文件做名称处理,目录的话不用处理,直接使用原名称 + if (fileName.lastIndexOf(".") != -1) { + fielType = fileName.substring(fileName.lastIndexOf(".")); + fileName = fileName.substring(0, fileName.lastIndexOf(".")); + } + } + + if(taskId!=null){ + fileName += "_" + taskId; + } + fileName += "_" + timestamp+""+((int)(Math.random()*1000)); + + if(StringUtils.isNotBlank(Contants.AGENT_LOCAL_IP)) { + fileName = fileName+"_"+Contants.AGENT_LOCAL_IP; + } + fileName += fielType; + logger.debug("回传文件名称为: "+fileName); + } catch (Exception e) + { + logger.error("Generating the name exception of the return file", e); + } + + return fileName; + } +} diff --git a/src/com/nis/nmsclient/thread/socket/SSLCertOper.java b/src/com/nis/nmsclient/thread/socket/SSLCertOper.java new file mode 100644 index 0000000..32cf8d0 --- /dev/null +++ b/src/com/nis/nmsclient/thread/socket/SSLCertOper.java @@ -0,0 +1,238 @@ +package com.nis.nmsclient.thread.socket; + +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.security.KeyStore; +import java.security.SecureRandom; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; + +import org.apache.log4j.Logger; + +import com.nis.nmsclient.common.Contants; +import com.nis.nmsclient.util.DateUtil; +import com.nis.nmsclient.util.Utils; + +public class SSLCertOper { + static Logger logger = Logger.getLogger(SSLCertOper.class); + + public static SSLContext getSSLContext() throws Exception { + // 初始化上下文 + SSLContext ctx = SSLContext.getInstance(Contants.SSL_JSSE_TYPE); + KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); + KeyStore ks = KeyStore.getInstance(Contants.SSL_KEYSTORE_TYPE); + ks.load(new FileInputStream(Contants.SSL_KEY_STORE), + Contants.SSL_KEY_STORE_PASS.toCharArray());// 载入keystore + kmf.init(ks, Contants.SSL_KEY_PRIVATE_PASS.toCharArray()); + + TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); + KeyStore tks = KeyStore.getInstance(Contants.SSL_KEYSTORE_TYPE); + tks.load(new FileInputStream(Contants.SSL_TRUST_KEY_STORE), + Contants.SSL_KEY_STORE_PASS.toCharArray());// 载入keystore + tmf.init(tks); + + ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), + new SecureRandom()); + logger.debug("load keystore success."); + + return ctx; + } + + /** + * 创建 密匙对(私钥和公钥) + * + */ + public static String createKeyAndCert(String aliasName, String storePath, + String localIp, String keyPass, String storePass, String certName) { + BufferedReader bReader = null; + Process process = null; + try { + process = Runtime.getRuntime().exec( + "keytool -genkey -v -alias " + aliasName + + " -keyalg RSA -storetype " + + Contants.SSL_KEYSTORE_TYPE + " -keystore " + + storePath + " -validity 90 -dname \"CN=" + + localIp + + ",OU=cn,O=cn,L=cn,ST=cn,C=cn\" -storepass " + + storePass + " -keypass " + keyPass); + process.getOutputStream().close(); + bReader = new BufferedReader(new InputStreamReader(process + .getInputStream())); + process.getErrorStream().close(); + String line = null; + while ((line = bReader.readLine()) != null) { + System.out.println(line); + } + + process = Runtime.getRuntime().exec( + "keytool -export -alias " + aliasName + " -storetype " + + Contants.SSL_KEYSTORE_TYPE + " -keystore " + + storePath + " -file " + certName + " -storepass " + + storePass + ""); + + bReader = new BufferedReader(new InputStreamReader(process + .getInputStream())); + while ((line = bReader.readLine()) != null) { + System.out.println(line); + } + + return certName; + } catch (IOException e) { + logger.error("Create a key pair error!"); + logger.error(Utils.printExceptionStack(e)); + return null; + } finally { + if (bReader != null) { + try { + bReader.close(); + } catch (IOException e) { + logger.error(Utils.printExceptionStack(e)); + } + } + } + + } + + /** + * 将公钥引入KeyStore + * + */ + public static boolean importCertToStore(String aliasName, String storePath, + String certName, String storePass) { + BufferedReader bReader = null; + PrintWriter pw = null; + try { + Process process = Runtime.getRuntime().exec( + "keytool -import -v -trustcacerts -alias " + aliasName + + " -keystore " + storePath + " -file " + certName + + " -storetype " + Contants.SSL_KEYSTORE_TYPE + + " -storepass " + storePass + ""); + + bReader = new BufferedReader(new InputStreamReader(process + .getInputStream())); + pw = new PrintWriter(process.getOutputStream()); + + pw.write("y"); + pw.flush(); + pw.close(); + + String line = null; + while ((line = bReader.readLine()) != null) { + System.out.println(line); + } + + return true; + } catch (IOException e) { + logger.error("Error of importing authentication certificate!"); + logger.error(Utils.printExceptionStack(e)); + return false; + } finally { + if (pw != null) { + pw.close(); + } + if (bReader != null) { + try { + bReader.close(); + } catch (IOException e) { + logger.error(Utils.printExceptionStack(e)); + } + } + } + + } + + /** + * 删除KeyStore库中的密钥 + * + */ + public static boolean deleteKeyOrCertFromStore(String aliasName, + String storePath, String storePass) { + BufferedReader bReader = null; + PrintWriter pw = null; + try { + Process process = Runtime.getRuntime().exec( + "keytool -delete -v -alias " + aliasName + " -keystore " + + storePath + " -storetype " + + Contants.SSL_KEYSTORE_TYPE + " -storepass " + + storePass + ""); + + bReader = new BufferedReader(new InputStreamReader(process + .getInputStream())); + pw = new PrintWriter(process.getOutputStream()); + + // pw.write("y"); + pw.flush(); + pw.close(); + + String line = null; + while ((line = bReader.readLine()) != null) { + System.out.println(line); + } + + return true; + } catch (IOException e) { + logger.error("Delete" + storePath+ "library Key" + aliasName + "make a mistake!"); + logger.error(Utils.printExceptionStack(e)); + return false; + } finally { + if (pw != null) { + pw.close(); + } + if (bReader != null) { + try { + bReader.close(); + } catch (IOException e) { + logger.error(Utils.printExceptionStack(e)); + } + } + } + + } + + /** + * test main + * + * @time Aug 28, 2011-12:17:28 PM + * @param args + */ + public static void main(String args[]) { + String newServerKeyName = "serverks" + + DateUtil.getCurrentDate(DateUtil.YYYYMMDD); + String newServerKeyPsw = "123456"; + String newClientkeyName = "clientks" + + DateUtil.getCurrentDate(DateUtil.YYYYMMDD); + String newClientkeyPsw = "123456"; + String filepath0 = SSLCertOper.createKeyAndCert(newServerKeyName, + "D:\\workspace\\nms_client\\src\\key\\server_ks", "10.0.6.120", + newServerKeyPsw, "server", + "D:\\workspace\\nms_client\\src\\key\\server.cer"); + + SSLCertOper.importCertToStore(newServerKeyName, + "D:\\workspace\\nms_client\\src\\key\\client_ts", + "D:\\workspace\\nms_client\\src\\key\\server.cer", "client"); + + String filepath1 = SSLCertOper.createKeyAndCert(newClientkeyName, + "D:\\workspace\\nms_client\\src\\key\\client_ks", "localhost", + newClientkeyPsw, "client", + "D:\\workspace\\nms_client\\src\\key\\client.cer"); + + SSLCertOper.importCertToStore(newClientkeyName, + "D:\\workspace\\nms_client\\src\\key\\server_ts", + "D:\\workspace\\nms_client\\src\\key\\client.cer", "server"); + System.out.println(filepath0); + System.out.println(filepath1); + // Config.setValueByName("ssl.server.key.old", + // Constants.SSL_SERVER_KEY_NEW); + // Config.setValueByName("ssl.server.key.old.psw", + // Constants.SSL_SERVER_KEY_NEW_PSW); + // Config.setValueByName("ssl.server.key.new",newServerKeyName); + // Config.setValueByName("ssl.server.key.new.psw", newServerKeyPsw); + // Config.setValueByName("ssl.client.key",newClientkeyName); + // Config.setValueByName("ssl.client.key.psw", newClientkeyPsw); + } +} diff --git a/src/com/nis/nmsclient/thread/socket/SSLClient.java b/src/com/nis/nmsclient/thread/socket/SSLClient.java new file mode 100644 index 0000000..db8dd6d --- /dev/null +++ b/src/com/nis/nmsclient/thread/socket/SSLClient.java @@ -0,0 +1,288 @@ +package com.nis.nmsclient.thread.socket; + +import java.io.File; +import java.util.List; +import java.util.concurrent.Callable; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; + +import net.sf.json.JSONArray; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + +import com.nis.nmsclient.common.Contants; +import com.nis.nmsclient.model.ReturnFilePO; +import com.nis.nmsclient.thread.task.TaskReqHandle; +import com.nis.nmsclient.thread.task.TaskResultOper; +import com.nis.nmsclient.util.FileUtil; +import com.nis.nmsclient.util.Utils; + + +/** + * 安全通讯的客户端 + **/ + +public class SSLClient extends CommonSocket implements Callable{ + Logger logger = Logger.getLogger(SSLClient.class); + private String name; + private String reqCmd; + private Object obj; + private String serverHost; + + public SSLClient(String name, String reqCmd, Object obj) { + this.name = name; + this.reqCmd = reqCmd; + this.obj = obj; + this.serverHost = Contants.SOCKET_SERVER_HOST; + } + + public SSLClient(String name, String reqCmd, Object obj, String serverHost) { + this.name = name; + this.reqCmd = reqCmd; + this.obj = obj; + this.serverHost = serverHost; + } + + /** + * 初始化客户端Socket + **/ + public void init() throws Exception { + SSLContext ctx = SSLCertOper.getSSLContext(); + SSLSocketFactory ssf = ctx.getSocketFactory(); + + socket = (SSLSocket) ssf.createSocket(serverHost, + Contants.SOCKET_SERVER_PORT); + logger.debug("create socket success."); + + //2014-1-23 hyx 如果建立socket成功,但是startHandshake握手失败,且未设置超时时间时,则会一直阻塞 + socket.setSoTimeout(1000 * 60 * Contants.SOCKET_TIMEOUT_MINUTES); + + ((SSLSocket) socket).startHandshake(); + logger.debug("handshake success."); + } + + @Override + public Object call() throws Exception { +// Thread.currentThread().setName(name + ">>通信 " + serverHost); + Thread.currentThread().setName(name + ">>Communication " + serverHost); + Object object = null; + try { + init(); + if(socket!=null){ + out = socket.getOutputStream(); + in = socket.getInputStream(); + //设置超时时间 + socket.setSoTimeout(1000 * 60 * Contants.SOCKET_TIMEOUT_MINUTES); + object = toDo(); + } + }catch (Exception e) { +// object = Contants.COMMON_MSG_FAIL + Contants.COMMON_MSG_SEPRATOR + "异常"; + object = Contants.COMMON_MSG_FAIL + Contants.COMMON_MSG_SEPRATOR + "anomaly"; + logger.error("Communication anomaly:" + Utils.printExceptionStack(e)); + } finally { + logger.debug("关闭通信"); + close(); + } + + return object; + } + + protected Object toDo() throws Exception { + logger.debug("发送通信请求:" + reqCmd); + //-- 无效操作处理 + if(StringUtils.isEmpty(reqCmd)){ + return null; + } + boolean flag = false; + String msg = null; + String result = null; + //-- 命令判断 + // 与Server通信 + if(reqCmd.equals(REQ_HAND_SHAKE)){ + flag = this.sendMessageByChar(reqCmd); + logger.debug("握手状态:" + (result = this.receiveMessageByChar())); + } + // 通知Server准备升级 + if(reqCmd.equals(REQ_SERVER_UPGRADE)){ + flag = this.sendMessageByChar(reqCmd); + result = this.receiveMessageByChar(); + } + // 获取本机标志UUID + if(reqCmd.equals(REQ_LOCAL_UUID)){ + flag = this.sendMessageByChar(reqCmd); + msg = this.receiveMessageByChar(); + flag = this.sendMessageByChar(CommonSocket.SUCCESS); + logger.info("本机标志UUID:" + msg); + } + //注释 by jinsj 2012-0531 修改为DC主动获取NC时间 + // 获取服务器系统时间 + if(reqCmd.equals(REQ_SERVER_SYSTEMDATE)){ + flag = this.sendMessageByChar(reqCmd); + msg = this.receiveMessageByChar(); + logger.debug("服务器系统时间:" + msg); + flag = this.sendMessageByChar(CommonSocket.SUCCESS); + } + // 发送本机的变更信息(操作系统类型和IP) + if(reqCmd.equals(REQ_LOCAL_CHANGE)){ + // 发送请求 + flag = this.sendMessageByChar(reqCmd); + result = this.receiveMessageByChar(); + // 发送信息: UUID$@$操作系统类型$@$LocalIP + flag = this.sendMessageByChar((String)obj); + // 接收变更结果: 0/1 $@$ 信息 + msg = this.receiveMessageByChar(); + flag = this.sendMessageByChar(CommonSocket.SUCCESS); + return msg; + } + // 初始化配置 + if(reqCmd.equals(REQ_INIT_CONFIG)){ + flag = this.sendMessageByChar(reqCmd); + msg = this.receiveMessageByChar();//接收配置信息 + flag = this.sendMessageByChar(CommonSocket.SUCCESS); + } + // 初始化任务 + if(reqCmd.equals(REQ_INIT_TASK)){ + // 发送请求 + flag = this.sendMessageByChar(reqCmd); + result = this.receiveMessageByChar(); + // 发送本机唯一标识 + flag = this.sendMessageByChar(Contants.AGENT_HOST_UUID + ""); + msg = this.receiveMessageByChar(); + flag = this.sendMessageByChar(CommonSocket.SUCCESS); + if (msg != null && !"".equals(msg)) { + JSONArray jsonArr = JSONArray.fromObject(msg); + //这里处理的任务,原则上不应含有”1 文件推送“类型的任务 + for (int i = 0; i < jsonArr.size(); i++) { + new TaskReqHandle().taskHandle(jsonArr.get(i).toString()); + } + } + logger.debug("初始化任务完成--" + msg); + return null; + } + // 发送主动告警信息 + if(reqCmd.equals(REQ_ALARM)){ + if(obj!=null){ + // 主动告警请求 + flag = this.sendMessageByChar(reqCmd); + result = this.receiveMessageByChar(); + // 发送主动告警信息内容 + flag = this.sendMessageByChar((String)obj); + logger.debug("主动告警信息:" + (String)obj); + result = this.receiveMessageByChar(); + }else{ + logger.debug("主动告警信息为空"); + } + } + // 发送任务结果 + if(reqCmd.equals(REQ_TASK_RESULT)){ + if(obj!=null){ + //发送任务结果请求 + flag = this.sendMessageByChar(reqCmd); + result = this.receiveMessageByChar(); + //发送任务结果内容 + flag = this.sendMessageByChar((String)obj); + result = this.receiveMessageByChar(); + }else{ + logger.warn("Task result information is empty"); + } + } + // 批量上传监测数据【数据收集方式改为DC主动后,此通信废弃】 + if(reqCmd.equals(REQ_UPLOAD_DATAS)){ + if(obj!=null && obj instanceof Object[]) { + Object[] objArr = (Object[])obj; + if (objArr != null && objArr.length > 1 && objArr[0] != null + && objArr[1] != null && objArr[1] instanceof List) { + //发送上传数据请求 + flag = this.sendMessageByChar(reqCmd); + result = this.receiveMessageByChar(); + //上传数据 + this.sendFileByBath((String) objArr[0], (List) objArr[1]); + result = this.receiveMessageByChar(); + }else{ + logger.warn("Uploading the contents of the monitored data object is incorrect"); + } + }else{ + logger.warn("Uploading monitoring data objects is empty"); + } + } + // 任务执行的回传文件:单个文件发送,断点续传【数据收集方式改为DC主动后,此类废弃】 + if(reqCmd.equals(REQ_TASK_RETURNFILE)){ + if(obj!=null && obj instanceof ReturnFilePO){ + ReturnFilePO rfPo = (ReturnFilePO)obj; + //发送回传文件请求 + flag = this.sendMessageByChar(reqCmd); + result = this.receiveMessageByChar(); + //发送回传文件任务信息 + this.sendMessageByChar(TaskResultOper.getTaskResultMsg(rfPo + .getTaskId(), rfPo.getTaskType(), null, null, null, rfPo + .getStartTime(), rfPo.getEndTime(), rfPo.getIsLoop())); + result = this.receiveMessageByChar(); + //发送回传文件文件名称 + this.sendMessageByChar(rfPo.getReturnFileName()); + result = this.receiveMessageByChar(); + //发送回传文件 + flag = this.bpSendFile(Contants.localTaskReturnPath + File.separator + rfPo.getReturnFileName()); + result = this.receiveMessageByChar(); + }else{ + logger.warn("The return file object is empty"); + } + } + + // 发送压缩文件,断点续传 + if(reqCmd.equals(REQ_BP_UPLOAD_FIFE)){ + if(obj!=null && obj instanceof String[]) { + String[] strArr = (String[])obj; + if (strArr != null && strArr.length > 1){ + //打包上传文件请求 + flag = this.sendMessageByChar(reqCmd + ":" + strArr[0]); + result = this.receiveMessageByChar(); + //发送打包文件名 + File file = new File(strArr[1]); + flag = this.sendMessageByChar(file.getName()); + result = this.receiveMessageByChar(); + //上传打包文件 + flag = this.bpSendFile(strArr[1]); + result = this.receiveMessageByChar(); + //上传成功后删除或移动文件 + if(flag && SUCCESS.equalsIgnoreCase(result) && file.exists()){ + String dataType = strArr[0]; + if(BP_TYPE_DETECT_DATA.equalsIgnoreCase(dataType)){ + FileUtil.moveFile(file, Contants.localDataDonePath, true); + }else if(BP_TYPE_TASK_RESULT.equalsIgnoreCase(dataType)){ + FileUtil.moveFile(file, Contants.localTaskDonePath, true); + }else if(BP_TYPE_TASK_RETURN.equalsIgnoreCase(dataType)){ + FileUtil.moveFile(file, Contants.localTaskDonePath, true); + } + } + } + } + } + // 向DC发送NC端异常信息 + if(reqCmd.equals(REQ_ERROR_INFO)){ + if(obj!=null){ + flag = this.sendMessageByChar(reqCmd); + result = this.receiveMessageByChar(); + //发送异常内容 + flag = this.sendMessageByChar((String)obj); + result = this.receiveMessageByChar(); + }else{ + logger.warn("Abnormal information is empty"); + } + } + + if (flag && (SUCCESS.equalsIgnoreCase(result) || msg!=null)) { + msg = Contants.COMMON_MSG_SUCCESS + Contants.COMMON_MSG_SEPRATOR + (msg!=null ? msg : "成功"); + } else { +// msg = Contants.COMMON_MSG_FAIL + Contants.COMMON_MSG_SEPRATOR + "失败"; + msg = Contants.COMMON_MSG_FAIL + Contants.COMMON_MSG_SEPRATOR + "failed"; + } + logger.debug("SSLClient toDo()---" + msg); + + logger.debug("发送通信请求结束:" + reqCmd); + // -- 命令判断 + return msg; + } +} \ No newline at end of file diff --git a/src/com/nis/nmsclient/thread/socket/SSLServer.java b/src/com/nis/nmsclient/thread/socket/SSLServer.java new file mode 100644 index 0000000..27852f8 --- /dev/null +++ b/src/com/nis/nmsclient/thread/socket/SSLServer.java @@ -0,0 +1,534 @@ +package com.nis.nmsclient.thread.socket; + +import java.io.File; +import java.io.IOException; +import java.net.Socket; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLServerSocket; +import net.sf.json.JSONObject; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.filefilter.FalseFileFilter; +import org.apache.commons.io.filefilter.PrefixFileFilter; +import org.apache.commons.lang.ArrayUtils; +import org.apache.log4j.Logger; +import com.nis.nmsclient.common.Common; +import com.nis.nmsclient.common.Contants; +import com.nis.nmsclient.common.SysConfig; +import com.nis.nmsclient.config.DetecConfReqHandle; +import com.nis.nmsclient.model.ReturnFilePO; +import com.nis.nmsclient.model.Task1; +import com.nis.nmsclient.model.Task4; +import com.nis.nmsclient.model.Task6; +import com.nis.nmsclient.thread.alarm.AlarmUtil; +import com.nis.nmsclient.thread.alarm.ErrorCode; +import com.nis.nmsclient.thread.task.AgentCommand; +import com.nis.nmsclient.thread.task.TaskReqHandle; +import com.nis.nmsclient.util.DateUtil; +import com.nis.nmsclient.util.FileUtil; +import com.nis.nmsclient.util.FileWrUtil; +import com.nis.nmsclient.util.Utils; + +/** + * 用于安全通讯的服务Socket,采用java中的SSLServerSocket + * 接收服务端发送过来的对该客户端的各配置参数信息,并对相应程序进行设置 + **/ +public class SSLServer implements Runnable { + static Logger logger = Logger.getLogger(SSLServer.class); + SSLServerSocket ss = null; + + private String startTime;// 服务启动时间 + + public SSLServer() throws IOException{ + init(); + } + + /** + * 初始化服务Socket + **/ + public void init() throws IOException { + try { + startTime = System.currentTimeMillis() + ""; + + //初始化上下文 + SSLContext ctx = SSLCertOper.getSSLContext(); + ss = (SSLServerSocket) ctx.getServerSocketFactory() + .createServerSocket(Contants.SOCKET_AGENT_PORT); + ss.setNeedClientAuth(true);// 客户端要认证 + } catch (Exception e) { + logger.error(Utils.printExceptionStack(e)); +// throw new IOException("NmsClient监听端口[" + Contants.SOCKET_AGENT_PORT + "]创建失败"); + throw new IOException("NmsClient monitor port[" + Contants.SOCKET_AGENT_PORT + "]Create failure"); + } + } + + /** + * 重载方法:run 处理客户端的请求 + **/ + public void run() { + logger.info("通讯线程启动 成功"); + Socket socket = null; + while(true){ + try { + socket = ss.accept(); + if(!Common.NC_UPGRADE_FLAG){//当NC_UPGRADE_FLAG为false时,允许建立通讯,否则放弃通讯,用于NC升级功能 + logger.debug("来自:"+socket.getInetAddress().getHostAddress()); + Common.service.submit(new ServerThread(socket)); + }else{ //关闭 放弃的通讯 + logger.info("NC升级 抛弃通讯:"+socket.getInetAddress().getHostAddress()); + socket.close(); + } + } catch (Exception e) { + logger.error("Failure to establish communication " + ss.getInetAddress().getHostAddress() + + ": " + Utils.printExceptionStack(e)); + } + } + + } + + class ServerThread extends CommonSocket implements Runnable { + + public ServerThread(Socket s) throws Exception { + super(s); + } + + public void run(){ + String ip = null; + try { + ip = socket.getInetAddress().getHostAddress(); + + //设置超时时间 + socket.setSoTimeout(1000 * 60 * Contants.SOCKET_TIMEOUT_MINUTES); + +// Thread.currentThread().setName("通讯线程 》" + socket.getInetAddress().getHostAddress()); + Thread.currentThread().setName("Communication Thread 》" + socket.getInetAddress().getHostAddress()); + + String msg = this.receiveMessageByChar(); + logger.info("接收请求 " + msg); + + if(REQ_HAND_SHAKE.equalsIgnoreCase(msg)){// 握手操作 + //返回接收到的信息和NMSClient启动时间 + this.sendMessageByChar(SUCCESS+":"+msg+"|"+startTime); + }else if(SERVER_COLLECT_DATA.equalsIgnoreCase(msg)){// DC主动向NC收集数据 + /** ----当前通信DC_IP与配置DC_IP不同,更新IP---- **/ + if(!Contants.SOCKET_SERVER_HOST.equals(ip)){ + logger.info("变更通信DC_IP: " + Contants.SOCKET_SERVER_HOST + " --> " + ip); + Contants.SOCKET_SERVER_HOST = ip; + /** ----SeqId未取到,更新配置文件---- **/ + if(Contants.AGENT_HOST_UUID == null){ + SysConfig.updateConfigFile(Contants.SOCKET_SERVER_HOST_KEY, Contants.SOCKET_SERVER_HOST); + } + } + new ServerCollectData(this).sendData(); + }else if(SERVER_GET_TASKRESULT.equalsIgnoreCase(msg)){// DC再次向NC获取未入库的任务结果 + this.sendMessageByChar(SUCCESS); + String taskInfo = null; + List fileList = new LinkedList(); + while(!END.equalsIgnoreCase(taskInfo = this.receiveMessageByChar())){ + // taskInfo组织顺序:TaskId、TaskType、isLoop、startTime、endTime + String[] infos = taskInfo.split(Contants.COMMON_MSG_SEPRATOR_SPLIT); + if (infos.length < 4 || (!"0".equals(infos[2]) && infos.length < 5)) {// 参数个数不够4,或者周期任务参数个数不够5,则跳过本次处理 + logger.warn("DC gets the task result again, the task attribute is incomplete, skip this processing."); + this.sendMessageByChar(AgentCommand.RESULT_FAIL +// + Contants.COMMON_MSG_SEPRATOR + "任务参数不全,找不到任务结果"); + + Contants.COMMON_MSG_SEPRATOR + "i18n_client.SSLServer.sendMsg_n81i"); + continue; + } + String eTime = null; + if(infos.length > 4){// 非周期任务,参数个数为4 + eTime = infos[4]; + } + // 检查指定任务的的结果或回传文件是否存在:若存在,移动到incoming目录;若不存在,回复失败 + boolean isExistResult = checkTaskResultExist(infos[0], infos[1], infos[2], infos[3], eTime, fileList); + if(isExistResult){ + this.sendMessageByChar(AgentCommand.RESULT_OK + + Contants.COMMON_MSG_SEPRATOR + ""); + } else { + this.sendMessageByChar(AgentCommand.RESULT_FAIL +// + Contants.COMMON_MSG_SEPRATOR + "任务结果不存在"); + + Contants.COMMON_MSG_SEPRATOR + "i18n_client.SSLServer.noResult_n81i"); + } + } + this.sendMessageByChar(SUCCESS); + // 移动存在的任务结果和回传文件 + moveTaskResultOrReturn(fileList); + }else if(REQ_SERVER_SYSTEMDATE.equalsIgnoreCase(msg)){//add by jinsj 2012-05-31 DC主动获取NC时间 + this.sendMessageByChar(new Date().getTime()+""); + this.receiveMessageByChar(); + }else if(Contants.AGENT_HOST_UUID == null ){ + // 除了以上三个通信,其他通信都得判断SeqID是否获取到,若未取到,则要放弃通讯 + logger.info("NC尚未取到SeqID 抛弃通讯:"+socket.getInetAddress().getHostAddress()); + close(); + return; + } + + if(REQ_CERT.equalsIgnoreCase(msg)){ + this.sendMessageByChar(SUCCESS); + //接收证书 + this.receiveFileByByte(Contants.keyPath + File.separator + "server.cer"); + this.sendMessageByChar(SUCCESS); + //导入认证证书到库 + SSLCertOper.importCertToStore("serverks" + + DateUtil.getCurrentDate(DateUtil.YYYYMMDD), + Contants.SSL_TRUST_KEY_STORE, + Contants.keyPath + File.separator + "server.cer", Contants.SSL_KEY_STORE_PASS); + File file = new File(Contants.keyPath + File.separator + "server.cer"); + if(file.exists()){ + FileUtil.delDir(file); + } + + /*SSLClient sc = new SSLClient(); + SSLCertOper.CreateAndSendCert(sc); + sc.close();*/ + }else if(SERVER_UPDATE_CONFIG.equalsIgnoreCase(msg)){// 更新监测配置 + this.sendMessageByChar(SUCCESS); + String str = this.receiveMessageByChar(); + this.sendMessageByChar(SUCCESS); + logger.debug("updateConfig-->" + str); + new DetecConfReqHandle().handlerConfigByUpdate(str); + } else if(SEND_PLUGIN_SCRIPT_FILE.equalsIgnoreCase(msg)) { // 下发脚本 + File pluginDir = new File(Contants.localPluginScriptPath); + this.sendMessageByChar(SUCCESS); + String fileNames = this.receiveMessageByChar(); + Collection files = FileUtils.listFiles(pluginDir, + new PrefixFileFilter(fileNames.split(",")), FalseFileFilter.FALSE); + for (Object file : files) { + ((File)file).delete(); + } + this.sendMessageByChar(SUCCESS); + this.bpReceiveFileByBath(pluginDir.getCanonicalPath()); + this.sendMessageByChar(SUCCESS); + + } else if(SERVER_FILE_PUSH.equalsIgnoreCase(msg)){//任务操作:文件推送 + this.sendMessageByChar(SUCCESS); + String str = this.receiveMessageByChar(); + logger.debug("task-->" + str); + this.sendMessageByChar(SUCCESS); + JSONObject jsonObj = JSONObject.fromObject(str); + String resultMsg = null; + if(str.contains("taskInfo")){ + JSONObject jsonObj2 = jsonObj.getJSONObject("taskInfo"); + Object obj = JSONObject.toBean(jsonObj2,Task1.class); + Task1 fileInfo = (Task1) obj; + // 接收文件 + resultMsg = new TaskReqHandle().filePush(this, fileInfo.getTaskParam(), fileInfo.getTaskId(), false); + } + if (resultMsg !=null && Contants.isSucessByResult(resultMsg)) { + this.sendMessageByChar(AgentCommand.RESULT_OK + + Contants.COMMON_MSG_SEPRATOR +// + "成功,详细信息如下:" + Contants.getDescByResult(resultMsg)); + + "i18n_client.SSLServer.success_n81i:" + Contants.getDescByResult(resultMsg)); + } else { + this.sendMessageByChar(AgentCommand.RESULT_FAIL + + Contants.COMMON_MSG_SEPRATOR +// + "失败,详细信息如下:" + Contants.getDescByResult(resultMsg)); + + "i18n_client.SSLServer.fail_n81i:" + Contants.getDescByResult(resultMsg)); + } + this.receiveMessageByChar(); + }else if(SERVER_UPGRADE.equalsIgnoreCase(msg)){//任务操作:升级 + this.sendMessageByChar(SUCCESS); + String str = this.receiveMessageByChar(); + logger.debug("task-->" + str); + this.sendMessageByChar(SUCCESS); + JSONObject jsonObj = JSONObject.fromObject(str); + String resultMsg = null; + TaskReqHandle handle = new TaskReqHandle(); + if(str.contains("taskInfo")){ + JSONObject jsonObj2 = jsonObj.getJSONObject("taskInfo"); + Object obj = JSONObject.toBean(jsonObj2,Task6.class); + Task6 task = (Task6) obj; + // 判断是否重新执行任务,并作提前处理 + reExecTask(task.getTaskId(), task.getOldTaskId()); + // 接收升级文件 + resultMsg = handle.filePush(this, task.getCommandParam(), + task.getTaskId(), true); + } + if (resultMsg !=null && Contants.isSucessByResult(resultMsg)) { + this.sendMessageByChar(AgentCommand.RESULT_SEND_OK + + Contants.COMMON_MSG_SEPRATOR +// + "下发成功,详细信息如下:" + Contants.getDescByResult(resultMsg)); + + "i18n_client.SSLServer.lssueSuccess_n81i:" + Contants.getDescByResult(resultMsg)); + } else { + this.sendMessageByChar(AgentCommand.RESULT_FAIL + + Contants.COMMON_MSG_SEPRATOR +// + "失败,详细信息如下: " + Contants.getDescByResult(resultMsg)); + + "i18n_client.SSLServer.fail_n81i: " + Contants.getDescByResult(resultMsg)); + } + String receiveMsg = this.receiveMessageByChar(); + if(resultMsg !=null && Contants.isSucessByResult(resultMsg) &&receiveMsg.equals(SUCCESS)){//处理升级 + handle.taskHandle(str); + } + }else if(SERVER_TASK.equalsIgnoreCase(msg)){//任务操作:命令执行和升级逆向任务 + this.sendMessageByChar(SUCCESS); + String str = this.receiveMessageByChar(); + logger.debug("task-->" + str); + this.sendMessageByChar(AgentCommand.RESULT_SEND_OK +// + Contants.COMMON_MSG_SEPRATOR + "下发成功"); + + Contants.COMMON_MSG_SEPRATOR + "i18n_client.SSLServer.lssueSuccess1_n81i"); + this.receiveMessageByChar(); + + //2015-6-23 针对reboot命令(之前存在会多次重启的问题,现修改为,接收到命令执行任务时,如果该任务的结果已经存在(incoming或者done里有),则不再执行) + try { + int taskType = 0; + JSONObject jsonObj = JSONObject.fromObject(str); + if(str.contains("typeInfo")){ + taskType = jsonObj.getInt("typeInfo"); + } + if(str.contains("taskInfo") && taskType==4){//taskType:命令执行任务(4) + JSONObject jsonObj2 = jsonObj.getJSONObject("taskInfo"); + Task4 task4 = (Task4)JSONObject.toBean(jsonObj2,Task4.class); + String taskId = task4.getTaskId()==null?"0":(task4.getTaskId()+""); + String isLoop = task4.getIsLoop()+""; + String startTime = task4.getStartTime()==null?"":task4.getStartTime()+""; + String endTime = task4.getEndTime()==null?"":task4.getEndTime()+""; + if(task4.getCommandType() == 2){//命令执行(4)->可执行命令(2) + logger.info("可执行命令 taskId:" + task4.getTaskId()); + List fileList = new ArrayList(); + boolean isExist = checkTaskResultExistFromDoneAndIncoming(taskId+"", taskType+"", isLoop, startTime, endTime, fileList);//非周期任务:0 + if(isExist) { + logger.info("任务已执行,不再重复执行:taskId:"+taskId+" taskType:"+taskType); + return; + } + } + } + } catch (Exception e) { + logger.error("For the next task, determine whether there is a result, if the result is no longer performing the exception", e); + } + + new TaskReqHandle().taskHandle(str); + }else if(SERVER_TASK_CANCEL.equalsIgnoreCase(msg)){//任务撤消操作 + this.sendMessageByChar(SUCCESS); + String str = this.receiveMessageByChar(); + logger.debug("taskcancle-->" + str); + if(str!=null && !"".equals(str)){ + Common.cancleTaskFuture(Long.parseLong(str), 0); + } + this.sendMessageByChar(AgentCommand.MISSION_CANCEL_FINISH +// + Contants.COMMON_MSG_SEPRATOR + "任务已撤消完成"); + + Contants.COMMON_MSG_SEPRATOR + "i18n_client.SSLServer.missionRevokeSuccess_n81i"); + this.receiveMessageByChar(); + }else if(ACTIVE_ALARM_START_ALERT.equalsIgnoreCase(msg)){// NC端是否报主动告警 变更 + this.sendMessageByChar(SUCCESS); + String str = this.receiveMessageByChar(); + this.sendMessageByChar(SUCCESS); + logger.debug("isStartActiveAlarm-->" + str); + JSONObject jsonObj = JSONObject.fromObject(str); + Boolean isStartActiveAlarm = (Boolean)jsonObj.get("showAutoAlarm"); + String webHandleTime = (String)jsonObj.get("webHandleTime"); + //更新Contants.ACTIIVE_ALARM_START + if(isStartActiveAlarm!=null) { + + Contants.ACTIIVE_ALARM_START = isStartActiveAlarm; + logger.info("NC是否主动告警:"+Contants.ACTIIVE_ALARM_START+" web端操作时间:"+webHandleTime); + } + } + + logger.debug("接收请求 " + msg + " 完成"); + } catch (Exception e) { + logger.error("Receiving information anomaly:" + Utils.printExceptionStack(e)); + if(ip==null){ + ip = Utils.getLocalIp(); + } +// AlarmUtil.sendNMSErrorMsg(ErrorCode.SocketError, ip , "NC通讯线程异常:" + e.getMessage()); + AlarmUtil.sendNMSErrorMsg(ErrorCode.SocketError, ip , "NC communication thread exception:" + e.getMessage()); + + return; + } finally { + logger.debug("关闭通信"); + close(); + } + } + + /** + * 重新执行任务,针对升级任务的推送文件的提前处理,将原任务的文件拷贝到新任务的临时目录 + * @param taskId + * @param oldTaskId + * @throws Exception + */ + private void reExecTask(Long taskId, Long oldTaskId) throws Exception { + // 如果原任务ID为空,说明不是重新执行任务,不执行任何操作 + if (oldTaskId == null || "".equals(oldTaskId.toString()) + || "0".equals(oldTaskId.toString())) { + return; + } + File tempDir = new File(Contants.localTempDataIncomingPath + File.separator + + "filepush_" + taskId); + if (!tempDir.exists()) { + tempDir.mkdirs(); + } + // 如果是升级任务,推送文件的保存路径getUpgradeTaskPushPath(taskId) + File oldFileDir = new File(TaskReqHandle.getUpgradeTaskPushPath(oldTaskId)); + try { + if(oldFileDir.exists()){ + FileUtils.copyDirectory(oldFileDir, tempDir); + } + } catch (IOException e) { + logger.error(e); + } + } + + /** + * DC再次获取任务结果 -- 检查指定任务的的结果或回传文件是否存在 + * @param isLoop 是否循环任务: 0 非周期, 1 周期 + * @param startTime 若非周期任务,升级时间或创建时间;若周期任务,某一周期的起始时间 + * @param endTime 若非周期任务,为空;若周期任务,某一周期的结束时间 + * @param fileList 用于存在找到的结果文件和回传文件 + * @return + */ + private boolean checkTaskResultExist(String taskId, String taskType, String isLoop, String sTime, String eTime, List fileList) throws Exception{ + long startTime=(sTime==null || "".equals(sTime) || "null".equals(sTime)) ? 0l : Long.parseLong(sTime); + long endTime=(eTime==null || "".equals(eTime) || "null".equals(eTime)) ? 0l : Long.parseLong(eTime); + logger.debug("checkTaskResultExist startTime=" + DateUtil.getStingDate(DateUtil.YYYY_MM_DD_HH24_MM_SS, new Date(startTime))+" -- endTime=" + DateUtil.getStingDate(DateUtil.YYYY_MM_DD_HH24_MM_SS, new Date(endTime))); + + String dateName = DateUtil.getStingDate(DateUtil.YYYYMMDD, new Date(startTime)); + String prefix = "tasktype" + taskType + "_" + taskId; + + boolean isExistResult = false; + // 依次取nc_task/done下的result和return目录 + File[] fileDirs = FileUtil.getDirectoryArray(new File(Contants.localTaskDonePath)); + if(fileDirs==null){ + logger.info("fileDirs为空"); + }else{ + try{ + for(File dir : fileDirs){ + // -- 找到指定的日期目录dateName及之后的日期目录 + File[] dateFiles = FileUtil.sortASCByFileName(FileUtil.getDirsAfterDateName(dir, dateName)); + // -- 在找到的日期目录下检查文件是否存在 + for(File dateFile : dateFiles){ + File[] files = null; + if("0".equals(isLoop)){// 0 非周期 + files = FileUtil.getFilesStartWith(dateFile, prefix); + }else{//--- 周期任务取某一时间段内的结果与回传文件 + files = FileUtil.getFilesStartWithByMillis(dateFile, prefix, startTime, endTime); + } + + if(files.length>0){// 若在任一目录下找到,则不用再找其他日期目录,跳出第二个For循环 + fileList.addAll(Arrays.asList(files)); + isExistResult = true; + break; + } + } + } + }catch(Exception e){ + logger.error(e); + } + } + if(!isExistResult){ + logger.info("再次获取任务结果 > TaskId: " + taskId + ", TaskType: " + + taskType + ", IsLoop: " + isLoop + " > 任务结果不存在"); + } + + return isExistResult; + } + + /** + * + * 检查done和incoming里是否有任务结果信息(如果有,则不进行再次执行,避免重复执行任务,如重复reboot) + * @author dell Jun 23, 2015 + * @version 1.0 + * @param taskId + * @param taskType + * @param isLoop + * @param sTime + * @param eTime + * @param fileList + * @return + * @throws Exception + */ + private boolean checkTaskResultExistFromDoneAndIncoming(String taskId, String taskType, String isLoop, String sTime, String eTime, List fileList) throws Exception{ + long startTime=(sTime==null || "".equals(sTime) || "null".equals(sTime)) ? 0l : Long.parseLong(sTime); + long endTime=(eTime==null || "".equals(eTime) || "null".equals(eTime)) ? 0l : Long.parseLong(eTime); + logger.debug("checkTaskResultExist startTime=" + DateUtil.getStingDate(DateUtil.YYYY_MM_DD_HH24_MM_SS, new Date(startTime))+" -- endTime=" + DateUtil.getStingDate(DateUtil.YYYY_MM_DD_HH24_MM_SS, new Date(endTime))); + + String dateName = DateUtil.getStingDate(DateUtil.YYYYMMDD, new Date(startTime)); + String prefix = "tasktype" + taskType + "_" + taskId; + + boolean isExistResult = false; + // 依次取nc_task/done和incoming下的result和return目录 + File[] fileDoneDirs = FileUtil.getDirectoryArray(new File(Contants.localTaskDonePath)); + File[] fileIncomingDirs = FileUtil.getDirectoryArray(new File(Contants.localTaskResultPath)); + File[] fileDirs = null; + if(fileIncomingDirs!=null && fileDoneDirs!=null) { + fileDirs = (File[])ArrayUtils.addAll(fileDoneDirs, fileIncomingDirs); + } + if(fileDirs==null){ + logger.info("fileDirs为空"); + }else{ + try{ + for(File dir : fileDirs){ + // -- 找到指定的日期目录dateName及之后的日期目录 + File[] dateFiles = FileUtil.sortASCByFileName(FileUtil.getDirsAfterDateName(dir, dateName)); + // -- 在找到的日期目录下检查文件是否存在 + for(File dateFile : dateFiles){ + File[] files = null; + if("0".equals(isLoop)){// 0 非周期 + files = FileUtil.getFilesStartWith(dateFile, prefix); + }else{//--- 周期任务取某一时间段内的结果与回传文件 + files = FileUtil.getFilesStartWithByMillis(dateFile, prefix, startTime, endTime); + } + + if(files.length>0){// 若在任一目录下找到,则不用再找其他日期目录,跳出第二个For循环 + fileList.addAll(Arrays.asList(files)); + isExistResult = true; + break; + } + } + } + }catch(Exception e){ + logger.error(e); + } + } + if(!isExistResult){ + logger.info("判断新下发的任务结果是否已经存在 > TaskId: " + taskId + ", TaskType: " + + taskType + ", IsLoop: " + isLoop + " > 任务结果不存在"); + }else { + logger.info("判断新下发的任务结果是否已经存在 > TaskId: " + taskId + ", TaskType: " + + taskType + ", IsLoop: " + isLoop + " > 任务结果已存在"); + } + + return isExistResult; + } + + /** + * DC再次获取任务结果 -- 移动找到的结果文件和回传文件到incoming目录 + */ + private void moveTaskResultOrReturn(List fileList){ + if(fileList==null || fileList.size()==0){ + return; + } + try { + for(File file : fileList){ + // ---------- 任务回传文件处理 + if(file.getName().endsWith(Contants.TASK_RETURN_FILE_SUFFIX)){ + if(!file.exists() || !file.isFile()){ + continue; + } + // 移动实际回传的文件 + String[] resultArr = FileWrUtil.cfgFileReader(file); + if (resultArr != null && resultArr.length > 0) { + JSONObject jsonObject = JSONObject.fromObject(resultArr[0]); + ReturnFilePO rfPo = (ReturnFilePO) JSONObject.toBean(jsonObject, ReturnFilePO.class); + if(rfPo.getReturnFileName()!=null && !"".equals(rfPo.getReturnFileName())){ + File returnFile = new File(file.getParent() + File.separator + rfPo.getReturnFileName()); + FileUtil.moveFile(returnFile, Contants.localTaskReturnPath, true); + } + } + // 移动记录任务回传的临时文件 + FileUtil.moveFile(file, Contants.localTaskReturnPath, true); + }else { + // ---------- 任务结果处理 + FileUtil.moveFile(file, Contants.localTaskResultPath, true); + } + } + } catch (Exception e) { + logger.error("Get the task result again > mobile file exception again", e); + } + } + } + +} \ No newline at end of file diff --git a/src/com/nis/nmsclient/thread/socket/ServerCollectData.java b/src/com/nis/nmsclient/thread/socket/ServerCollectData.java new file mode 100644 index 0000000..fa55551 --- /dev/null +++ b/src/com/nis/nmsclient/thread/socket/ServerCollectData.java @@ -0,0 +1,581 @@ +package com.nis.nmsclient.thread.socket; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; + +import net.sf.json.JSONObject; + +import org.apache.log4j.Logger; + +import com.nis.nmsclient.common.Contants; +import com.nis.nmsclient.model.ReturnFilePO; +import com.nis.nmsclient.thread.task.TaskResultOper; +import com.nis.nmsclient.util.DateUtil; +import com.nis.nmsclient.util.FileUtil; +import com.nis.nmsclient.util.FileWrUtil; +import com.nis.nmsclient.util.StringUtil; +import com.nis.nmsclient.util.Utils; +import com.nis.nmsclient.util.ZipUtil; + +/** + * 用于定时扫描并上传监测数据文件 + * + **/ +public class ServerCollectData { + Logger logger = Logger.getLogger(ServerCollectData.class); + private CommonSocket socket; + + public ServerCollectData(CommonSocket socket) { + this.socket = socket; + } + + public void sendData() { + logger.debug("传送数据开始 ~~~~~~~"); + try { + // 发送监测数据 + handleDetectData(); + // 发送任务结果 + handleTaskResult(); + // 发送任务回传文件 + handleTaskReturnFile(); + // 发送任务结果--针对有回传文件时写的任务结果 + handleTaskResult(); + // 结束通讯 + socket.sendMessageByChar(CommonSocket.END); + + } catch (Exception e) { + logger.error("Transmits data anomalies:" + Utils.printExceptionStack(e)); + } + logger.debug("传送数据结束 ~~~~~~~"); + } + + private void handleDetectData() throws Exception { + logger.debug("传送监测数据开始 ~~~~~~~"); + long startTime = System.currentTimeMillis(); + File parDir = new File(Contants.localDataCollection); + if(!parDir.exists()){ + return; + } + // == 1、针对数据文件过多时打包上传未完成的文件继续上传 + // ------------取所有未上传完成的Zip文件 + List fileList = new LinkedList(); + File[] fileArr = FileUtil.getFilesEndWith(parDir, ".zip"); + if (fileArr != null && fileArr.length > 0) { + for (File file : fileArr) { + if (!file.getName().startsWith(CommonSocket.BP_TYPE_DETECT_DATA)) { + continue; + } + fileList.add(file); + } + } + // ------------传送Zip文件 + if (fileList.size() > 0) { + sendZipFile(fileList, CommonSocket.DATA_TYPE_ZIP_DETECT); + } + + // == 2、检查当前数据文件数量,批量发送文件或打包上传 + File dataDir = new File(Contants.localDataFilePath); + if (!dataDir.exists()) { + logger.warn("Data directory“" + dataDir.getAbsolutePath() + "”Non-existent!!!"); + } else { + long total = 0; + List allFiles = new ArrayList(); + File[] dataDirs = FileUtil.getDirectoryArray(dataDir); + // ---- 数据处理 + total = handleNullDataFile(allFiles, dataDirs); + logger.info("本次收集监测数据文件总数:" + total + ", 正常数据:" + allFiles.size() + ", 空数据:" + (total - allFiles.size())); + total = allFiles.size();// 正常的要上传的数据个数 + + // --- 将所有数据文件一起打包,发送 + if (total > Contants.COMMON_ZIP_MIN_SIZE) { + long zipCnt = total/Contants.COMMON_ZIP_MAX_SIZE; + if (zipCnt > 0) {//2013-5-6 未上传的数据太多时,将监测数据压缩为多个文件 + for(int i=0; i 0) { + // -- 按正常所有监测数据批量上传 + sendCSVData(dataDir, allFiles); + logger.info("本次收集传送监测数据总数:" + total + ",用时:" + + (System.currentTimeMillis() - startTime) + "ms"); + } else { + logger.info("本次收集未传送监测数据"); + } + } + logger.debug("传送监测数据结束 ~~~~~~~"); + } + + private void handleTaskResult() throws Exception { + logger.debug("传送任务结果开始 ~~~~~~~"); + long startTime = System.currentTimeMillis(); + // == 1、针对结果文件过多时打包上传未完成的文件继续上传 + File taskDir = new File(Contants.localTaskPath); + if (!taskDir.exists()) { + return; + } + // ------------取所有未上传完成的Zip文件 + List fileList = new LinkedList(); + File[] zipArr = FileUtil.getFilesEndWith(taskDir, ".zip"); + if (zipArr != null && zipArr.length > 0) { + for (File file : zipArr) { + if (!file.getName().startsWith(CommonSocket.BP_TYPE_TASK_RESULT)) { + continue; + } + fileList.add(file); + } + } + // ------------传送Zip文件 + if(fileList.size()>0){ + sendZipFile(fileList, CommonSocket.DATA_TYPE_ZIP_TASKRESULT); + } + + // == 2、检查当前结果文件数量,批量发送文件或打包上传 + File resultDir = new File(TaskResultOper.getTaskResultPath()); + if(!resultDir.exists()){ + return; + } + File[] fileArr = FileUtil.getFilesEndWith(resultDir, Contants.TASK_RESULT_FILE_SUFFIX); + // -- 将所有任务结果文件一起打包,发送 + if(fileArr.length > Contants.COMMON_ZIP_MIN_SIZE){ + int zipCnt = fileArr.length/Contants.COMMON_ZIP_MAX_SIZE; + if(zipCnt>0){//2013-5-6 未上传的结果文件太多时,将结果文件压缩为多个文件 + for(int i=0; i 0){ + // -- 按正常的多个结果批量发送 + sendTaskResult(fileArr); + logger.info("本次收集传送任务结果总数:" + fileArr.length + ",用时:" + + (System.currentTimeMillis() - startTime) + "ms"); + } else { + logger.info("本次收集未传送任务结果"); + } + logger.debug("传送任务结果结束 ~~~~~~~"); + } + + private void handleTaskReturnFile() throws Exception { + logger.debug("传送回传文件开始 ~~~~~~~"); + long startTime = System.currentTimeMillis(); + // == 1、针对回传文件过多时打包上传未完成的文件继续上传 + File taskDir = new File(Contants.localTaskPath); + if (!taskDir.exists()) { + return; + } + // ------------取所有未上传完成的Zip文件 + List fileList = new LinkedList(); + File[] zipArr = FileUtil.getFilesEndWith(taskDir, ".zip"); + if (zipArr != null && zipArr.length > 0) { + for (File file : zipArr) { + if (!file.getName().startsWith(CommonSocket.BP_TYPE_TASK_RETURN)) { + continue; + } + fileList.add(file); + } + } + // ------------传送Zip文件 + if(fileList.size()>0){ + sendZipFile(fileList, CommonSocket.DATA_TYPE_ZIP_TASKRETURN); + } + + // == 2、检查当前回传文件数量,单个发送文件或打包上传 + File returnDir = new File(Contants.localTaskReturnPath); + if(!returnDir.exists()){ + return; + } + File[] fileArr = FileUtil.getFilesEndWith(returnDir, Contants.TASK_RETURN_FILE_SUFFIX); + if(fileArr == null || fileArr.length == 0){ + return; + } + //--- 将所有任务的回传文件及回传信息保存文件一起打包,发送 + if(fileArr.length > Contants.COMMON_MAX_RETURN_CNT){ + //压缩并删除原文件 + String compressFileStr = Contants.localTaskPath + + File.separator + + CommonSocket.addTimeTagForFileName(CommonSocket.BP_TYPE_TASK_RETURN, + null, true) + + ".zip"; + // 2013-03-22 由于DC再次获取未保存任务结果这个功能的实现,现修改将任务结果和回传文件压缩时不删除文件,而是将其移动到相应的日期目录 + ZipUtil.zipWithMoveFile(returnDir.listFiles(), compressFileStr, false); + //发送 + sendZipFile(new File(compressFileStr), CommonSocket.DATA_TYPE_ZIP_TASKRETURN); + logger.info("本次收集将所有任务回传文件打包传送,回传文件总数:" + fileArr.length + ",用时:" + (System.currentTimeMillis() - startTime) + "ms"); + }else if(fileArr.length > 0){ + //-- 按正常的一个任务一个任务的回传 + sendTaskReturn(fileArr); + logger.info("本次收集传送任务回传总数:" + fileArr.length + ",用时:" + + (System.currentTimeMillis() - startTime) + "ms"); + } else { + logger.info("本次收集未传送任务回传文件"); + } + logger.debug("传送回传文件结束 ~~~~~~~"); + } + + /** + * 遍历所有准备上传的数据文件,将空数据文件移动到指定目录,并记录所有文件总数 + * @param allFiles 所有非空文件集合 + * @param dataDirs 所有数据目录 + * @return 所有文件个数(包括空文件) + * @throws Exception + */ + private long handleNullDataFile(List allFiles, File[] dataDirs) throws Exception { + long total = 0l; + for(File dir : dataDirs){ + File[] files = FileUtil.getFilesEndWith(dir, ".csv"); + if(files==null || files.length==0){ + continue; + } + files = FileUtil.sortASCByModify(files); // 修改日期升序排序 + total += files.length; + for (File file : files) { + if (file.length() > 0) { + allFiles.add(file); + continue; + } + //--- 处理空文件数据:移动空文件数据到指定日期目录 + String dirTime = DateUtil.getStingDate( + DateUtil.YYYYMMDD, + new Date(file.lastModified())); + String newDir = Contants.localDataErrorPath + + File.separator + + file.getParentFile().getName() + + File.separator + dirTime; + FileUtil.moveFile(file, newDir, true); + } + } + return total; + } + + private void compressAndSendDetecData(File[] dataFiles) throws Exception{ + // 压缩并移动原文件 + String compressFileStr = Contants.localDataCollection + + File.separator + + CommonSocket.addTimeTagForFileName( + CommonSocket.BP_TYPE_DETECT_DATA, null, true) + + ".zip"; + // 2013-3-29 由于压缩上传数据后,主动告警线程部分对数据检查存在问题,现将压缩后删除数据改为移动数据到日期目录 + ZipUtil.zipWithMoveFile(dataFiles, compressFileStr, true); + // 发送 + sendZipFile(new File(compressFileStr), CommonSocket.DATA_TYPE_ZIP_DETECT); + } + + private void compressAndSendTaskResult(File[] resultFiles) throws Exception { + //压缩并删除原文件 + String compressFileStr = Contants.localTaskPath + + File.separator + + CommonSocket.addTimeTagForFileName(CommonSocket.BP_TYPE_TASK_RESULT, null, true) + + ".zip"; + // 2013-03-22 由于DC再次获取未保存任务结果这个功能的实现,现修改将任务结果和回传文件压缩时不删除文件,而是将其移动到相应的日期目录 + ZipUtil.zipWithMoveFile(resultFiles, compressFileStr, true); + //发送 + sendZipFile(new File(compressFileStr), CommonSocket.DATA_TYPE_ZIP_TASKRESULT); + } + + private void compressAndSendTaskReturn(File[] returnFiles) throws Exception { + //压缩并删除原文件 + String compressFileStr = Contants.localTaskPath + + File.separator + + CommonSocket.addTimeTagForFileName(CommonSocket.BP_TYPE_TASK_RETURN, + null, true) + + ".zip"; + // 2013-03-22 由于DC再次获取未保存任务结果这个功能的实现,现修改将任务结果和回传文件压缩时不删除文件,而是将其移动到相应的日期目录 + ZipUtil.zipWithMoveFile(returnFiles, compressFileStr, false); + //发送 + sendZipFile(new File(compressFileStr), CommonSocket.DATA_TYPE_ZIP_TASKRETURN); + } + + /** + * 发送打包文件:整个命令通信包装方法 + * @param file + * @throws Exception + */ + private void sendZipFile(File file, String dataType) throws Exception { + //打包上传文件请求 + socket.sendMessageByChar(dataType); + socket.receiveMessageByChar(); + socket.sendMessageByChar(file.getName());//发送打包文件名 + socket.receiveMessageByChar(); + //上传打包文件 + socket.bpSendFile(file.getAbsolutePath()); + String result = socket.receiveMessageByChar(); + //上传成功后移动文件 + if(CommonSocket.SUCCESS.equalsIgnoreCase(result)){ + if(CommonSocket.DATA_TYPE_ZIP_DETECT.equalsIgnoreCase(dataType)){ + FileUtil.moveFile(file, Contants.localDataDonePath, true); + }else if(CommonSocket.DATA_TYPE_ZIP_TASKRESULT.equalsIgnoreCase(dataType)){ + FileUtil.moveFile(file, Contants.localTaskDonePath, true); + }else if(CommonSocket.DATA_TYPE_ZIP_TASKRETURN.equalsIgnoreCase(dataType)){ + FileUtil.moveFile(file, Contants.localTaskDonePath, true); + } + } + } + + private void sendZipFile(List fileList, String dataType) throws Exception { + for(File file : fileList){ + sendZipFile(file, dataType); + } + } + + // 批量发送ZIP的 + /*private void sendZipFile(List fileList, String parDir) throws Exception { + //打包上传文件请求 + socket.sendMessageByChar(CommonSocket.DETECT_DATA_TYPE_ZIP); + socket.receiveMessageByChar(); + //上传打包文件 + socket.bpSendFileByBath(fileList, parDir); + String result = socket.receiveMessageByChar(); + //上传成功后移动文件 + if(CommonSocket.SUCCESS.equalsIgnoreCase(result)){ + for(File file : fileList){ + FileUtil.moveFile(file, Contants.localDataDonePath, true); + } + } + }*/ + + /** + * 批量发送CSV数据文件 + * @param dataDir + * @param allFiles + * @throws Exception + */ + private void sendCSVData(File dataDir, List allFiles) throws Exception { + //发送上传数据请求 + socket.sendMessageByChar(CommonSocket.DATA_TYPE_CSV_DETECT); + socket.receiveMessageByChar(); + //上传数据 + socket.sendFileByBath(dataDir.getParent(), allFiles); + String result = socket.receiveMessageByChar(); + if (CommonSocket.SUCCESS.equalsIgnoreCase(result)) { + /** + * 移动上传成功的数据文件到指定日期目录 + */ + File[] files = new File[allFiles.size()]; + moveDetecDataToDateDir(allFiles.toArray(files)); + } + } + + /** + * 批量发送任务结果 + * @param fileArr + * @throws Exception + */ + private void sendTaskResult(File[] fileArr) throws Exception { + //2013-4-16 修改升序排列方式:按修改时间 改为 按文件名,任务结果文件名都有时间后缀(ms),文件修改时间只到s取不到ms + fileArr = FileUtil.sortASCByFileName(fileArr); + List results = new LinkedList(); + StringBuffer sb = new StringBuffer(); + for(File file : fileArr){ + sb.delete(0, sb.length()); + if(!file.exists() || !file.isFile()){ + continue; + } + String[] resultArr = FileWrUtil.cfgFileReader(file); + if(resultArr!=null && resultArr.length>0){ + for(String res : resultArr){ + sb.append(res + ";"); + } + sb.deleteCharAt(sb.length()-1); + results.add(sb.toString()); + } + } + logger.debug("sendTaskResult-->" + Arrays.toString(results.toArray())); + //发送任务结果请求 + socket.sendMessageByChar(CommonSocket.DATA_TYPE_OBJ_TASKRESULT); + socket.receiveMessageByChar(); + //发送任务结果内容 + socket.sendObject(results); + String result = socket.receiveMessageByChar(); + if (CommonSocket.SUCCESS.equalsIgnoreCase(result)) { + // 移动上传成功的任务结果到指定日期目录 + moveTaskResultToDateDir(fileArr); + } + } + /** + * 单个发送任务回传文件 + * @param fileArr + * @throws Exception + */ + private void sendTaskReturn(File[] fileArr) throws Exception { + fileArr = FileUtil.sortASCByModify(fileArr); //修改日期升序排序 + for(File file : fileArr){ + if(!file.exists() || !file.isFile()){ + continue; + } + String[] resultArr = FileWrUtil.cfgFileReader(file); + if (resultArr == null || resultArr.length <= 0) { + continue; + } + JSONObject jsonObject = JSONObject.fromObject(resultArr[0]); + ReturnFilePO rfPo = (ReturnFilePO) JSONObject.toBean(jsonObject, ReturnFilePO.class); + + //--回传文件名和回传描述信息均为空时,则无回传文件 + if(StringUtil.isEmpty(rfPo.getReturnFileName()) && StringUtil.isEmpty(rfPo.getResDesc())){ + logger.warn("No return file, no return"); + FileUtil.delDir(file); + continue; + } + //--回传文件名为空,但回传描述信息不为空,则进行步骤2发送任务结果、删除文件 + /** + * 步骤1、回传文件 + */ + StringBuffer sb = new StringBuffer(); + if(rfPo.getResDesc()!=null){//取已有的结果描述信息 + sb.append(rfPo.getResDesc()); + } + //准备回传文件,回传文件名不为空即有回传的文件时,再回传 + boolean success = false; + if(rfPo.getReturnFileName()!=null && rfPo.getReturnFileName().trim().length()>0){ + //发送回传文件请求 + socket.sendMessageByChar(CommonSocket.DATA_TYPE_FILE_TASKETURN); + socket.receiveMessageByChar(); + //发送回传文件任务信息 + socket.sendMessageByChar(TaskResultOper.getTaskResultMsg(rfPo + .getTaskId(), rfPo.getTaskType(), null, null, null, rfPo + .getStartTime(), rfPo.getEndTime(), rfPo.getIsLoop())); + socket.receiveMessageByChar(); + //发送回传文件文件名称 + socket.sendMessageByChar(rfPo.getReturnFileName()); + socket.receiveMessageByChar(); + //发送回传文件 + socket.bpSendFile(Contants.localTaskReturnPath + File.separator + rfPo.getReturnFileName()); + String result = socket.receiveMessageByChar(); + success = true; +// sb.append("回传成功"); + sb.append("i18n_client.ServerCollectData.transFile_n81i"); + }else{ + success = true; + } + + /** + * 步骤2、判断文件是否回传完成 + */ + if(success){ + /** + * 步骤2-1、发送任务结果 + */ + TaskResultOper.sendTaskResult(rfPo.getTaskId(), rfPo.getTaskType(), + rfPo.getState(), sb.toString(), "", rfPo.getStartTime(), + rfPo.getEndTime(), false, rfPo.getIsLoop()); + /** + * 步骤2-2、移动上传成功的 保存回传文件信息的文件 和 回传文件 到指定日期目录 + */ + moveTaskReturnToDateDir(file, rfPo.getReturnFileName()); + } + } + } + + + /** + * 移动上传成功的任务结果到指定日期目录 + * 完整文件到目录:.../done/result/yyyyMMdd + * 0大小文件到目录: .../error/result/yyyyMMdd + */ + public static void moveTaskResultToDateDir(File... fileArr){ + if(fileArr==null || fileArr.length==0){ + return; + } + for (File file : fileArr) { + String dirTime = DateUtil.getStingDate( + DateUtil.YYYYMMDD, + new Date(file.lastModified())); + String newDir = ""; + if (file.length() > 0) { + newDir = Contants.localTaskDonePath + + File.separator + + file.getParentFile().getName() + + File.separator + dirTime; + } else { + newDir = Contants.localTaskErrorPath + + File.separator + + file.getParentFile().getName() + + File.separator + dirTime; + } + // -- 文件移动 + FileUtil.moveFile(file, newDir, true); + } + } + + /** + * 移动上传成功的 保存回传文件信息的文件 和 回传文件 到指定日期目录 + * 完整文件到目录:.../done/return/yyyyMMdd + * 0大小文件到目录: .../error/return/yyyyMMdd + */ + public static void moveTaskReturnToDateDir(File file, String returnFileName){ + String dirTime = DateUtil.getStingDate( + DateUtil.YYYYMMDD, + new Date(file.lastModified())); + String newDir = Contants.localTaskDonePath + + File.separator + + file.getParentFile().getName() + + File.separator + dirTime; + // -- 文件移动 + FileUtil.moveFile(file, newDir, true);// 保留任务信息的临时文件.return + if(returnFileName!=null && !"".equals(returnFileName)){// 实际回传的文件 + File curReturnFile = new File(Contants.localTaskReturnPath + File.separator + returnFileName); + FileUtil.moveFile(curReturnFile, newDir, true); + } + + } + + /** + * 移动上传成功的数据文件到指定日期目录 + * 完整文件到目录:.../done/type_procIden/yyyyMMdd + * 0大小文件到目录: .../error/type_procIden/yyyyMMdd + */ + public static void moveDetecDataToDateDir(File... allFiles){ + if(allFiles==null || allFiles.length==0){ + return; + } + for (File file : allFiles) { + String dirTime = DateUtil.getStingDate( + DateUtil.YYYYMMDD, + new Date(file.lastModified())); + String newDir = ""; + if (file.length() > 0) { + newDir = Contants.localDataDonePath + + File.separator + + file.getParentFile().getName() + + File.separator + dirTime; + } else { + newDir = Contants.localDataErrorPath + + File.separator + + file.getParentFile().getName() + + File.separator + dirTime; + } + // -- 文件移动 + FileUtil.moveFile(file, newDir, true); + } + } + +} \ No newline at end of file diff --git a/src/com/nis/nmsclient/thread/task/AgentCommand.java b/src/com/nis/nmsclient/thread/task/AgentCommand.java new file mode 100644 index 0000000..c165fef --- /dev/null +++ b/src/com/nis/nmsclient/thread/task/AgentCommand.java @@ -0,0 +1,1928 @@ + package com.nis.nmsclient.thread.task; + +import java.io.File; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import net.sf.json.JSONObject; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + +import com.nis.nmsclient.common.Common; +import com.nis.nmsclient.common.Contants; +import com.nis.nmsclient.common.VersionCfg; +import com.nis.nmsclient.model.CommandPO; +import com.nis.nmsclient.model.ParamBackup; +import com.nis.nmsclient.model.ParamCmdExec; +import com.nis.nmsclient.model.ParamCoverUpdate; +import com.nis.nmsclient.model.ParamUpgrade; +import com.nis.nmsclient.model.ReturnFilePO; +import com.nis.nmsclient.thread.socket.CommonSocket; +import com.nis.nmsclient.thread.socket.SSLClient; +import com.nis.nmsclient.util.CompressFileMgr; +import com.nis.nmsclient.util.FileUtil; +import com.nis.nmsclient.util.FileWrUtil; +import com.nis.nmsclient.util.ProcessUtil; +import com.nis.nmsclient.util.Utils; + +public class AgentCommand { + static Logger logger = Logger.getLogger(AgentCommand.class); + public static final int RESULT_OK = 0; + public static final int RESULT_FAIL = 1; + public static final int RESULT_SEND_OK = 40; + public static final int RESULT_SEND_FAIL = 41; + public static final int RESULT_KILL_OK = 50; + public static final int RESULT_KILL_FAIL = 51; + public static final int RESULT_BACKUP_OK = 60; + public static final int RESULT_BACKUP_FAIL = 61; + public static final int RESULT_UPDATE_OK = 70; + public static final int RESULT_UPDATE_FAIL = 71; + public static final int RESULT_START_OK = 80; + public static final int RESULT_START_FAIL = 81; + public static final int RESULT_RECOVER_OK = 90; + public static final int RESULT_RECOVER_FAIL = 91; + public static final int MISSION_CANCEL_CREATE = 5;//任务准备撤消 + public static final int MISSION_CANCEL_START = 6;//任务撤消中 + public static final int MISSION_CANCEL_FINISH = 7;//任务撤消完成 + + private static final String RESULT_SEPRATOR = Contants.COMMON_MSG_SEPRATOR; + private static final String RESULT_SEPRATOR_SPLIT = Contants.COMMON_MSG_SEPRATOR_SPLIT; + + public static enum UpgradeSteps { + upgrade_agent, upgrade_other, + upgrade_server, upgrade_kill_process, + upgrade_backup, upgrade_update, + upgrade_start, upgrade_recover, + upgrade_exec, single_exec; + } + public static final String PARAM_SEPRATOR = "@&##&@"; + + // NC/DC升级锁,确保NC与DC不同时升级 + private static final Byte[] upgradeLock = new Byte[0]; + + private CommandPO command; + private Thread thread; + + public AgentCommand(CommandPO command) { + super(); + this.command = command; + } + + public boolean exec(){ + Date execTime = new Date(); +// String resultDesc = "执行失败"; +// String resultDesc = "Failure to execute"; + String resultDesc = "i18n_client.AgentCommand.execFail_n81i"; + long resultState = RESULT_FAIL; + boolean isServer = false; + try { + String commandParam = command.getCommandParam(); + if(commandParam==null || "".equals(commandParam)){ +// resultDesc = "执行失败:命令参数为空"; +// resultDesc = "Execution failure: command parameters are empty"; + resultDesc = "i18n_client.AgentCommand.execFailDesc1_n81i"; + resultState = RESULT_FAIL; +// logger.warn(resultDesc);//i18nlog + } else { + logger.debug("commandParam 1--" + commandParam); + //2012-4-28 任务参数中对路径的格式化将在界面上进行,原因此处会对转义字符的\也转换为/,故replace("\\", "/")去掉 + commandParam = commandParam.trim().replaceAll("[\n\t\r]","");//.replace("\\", "/");//[\\s*\n\t\r] + logger.debug("commandParam 2--" + commandParam); + String[] params = commandParam.trim().split(PARAM_SEPRATOR); + if (params != null && params.length >= 1) { + for(int i=0; iparam: " + params[i]); + ParamBackup backup = (ParamBackup) JSONObject + .toBean(JSONObject.fromObject(params[i]), + ParamBackup.class); + backups[i] = backup; + } + resultStr = backupCmd(backups, null, command + .getExecId()); + break; + case upgrade_update:// 命令参数,以;分隔多个CoverUpdate对象的Json字符串 + case upgrade_recover:// 命令参数,以;分隔多个CoverUpdate对象的Json字符串 + ParamCoverUpdate[] updates = new ParamCoverUpdate[params.length]; + for (int i = 0; i < params.length; i++) { + logger.debug("updateCmd-->param: " + params[i]); + ParamCoverUpdate update = (ParamCoverUpdate) JSONObject + .toBean(JSONObject.fromObject(params[i]), + ParamCoverUpdate.class); + updates[i] = update; + } + resultStr = updateCmd(updates); + break; + case upgrade_start:// 命令参数,以;分隔多个CmdExec对象的Json字符串 + case upgrade_exec:// 可执行命令 + List execList = new ArrayList(); + for (String param : params) { + logger.debug("startCmd-->param: " + param); + ParamCmdExec exec = (ParamCmdExec) JSONObject + .toBean(JSONObject.fromObject(param), + ParamCmdExec.class); + execList.add(exec); + } + resultStr = startCmd(execList, execTime, false, command.getExecState()); + break; + case single_exec:// 单次执行命令,命令参数,以;分隔多个CmdExec对象的Json字符串 + List cmdExecList = new ArrayList(); + for (String param : params) { + logger.debug("singleExecCmd-->param: " + param); + ParamCmdExec exec = (ParamCmdExec) JSONObject + .toBean(JSONObject.fromObject(param), + ParamCmdExec.class); + cmdExecList.add(exec); + } + resultStr = singleExecCmd(cmdExecList, execTime, command.getExecState()); + break; + + default: +// resultDesc = "执行失败,不存在该命令"; +// resultDesc = "The execution failed and the command did not exist"; + resultDesc = "i18n_client.AgentCommand.execFailDesc2_n81i"; + resultState = RESULT_FAIL; +// logger.warn(resultDesc);//i18nlog + break; + } + + String[] res = resultStr.split(RESULT_SEPRATOR_SPLIT); + if (res != null && res.length >= 2) { + resultState = Long.parseLong(res[0]); + resultDesc = res[1]; + } + } else { +// resultDesc = "执行失败:命令参数不正确<" + commandParam + ">"; +// resultDesc = "Execution failure: incorrect command parameters<" + commandParam + ">"; + resultDesc = "i18n_client.AgentCommand.execFailDesc3_n81i<" + commandParam + ">"; + resultState = RESULT_FAIL; +// logger.warn(resultDesc);//i18nlog + } + + } + } catch (Exception e) { +// resultDesc = "执行失败:出现异常,详细信息请查看日志"; +// resultDesc = "Execution failure: abnormal. Please check log for details"; + resultDesc = "i18n_client.AgentCommand.execFailDesc4_n81i"; + resultState = RESULT_FAIL; +// logger.error(resultDesc + "\n" + Utils.printExceptionStack(e));//i18nlog + } + + // 发送信息 + TaskResultOper.sendTaskResult(command.getExecId(), command.getExecType(), + resultState, resultDesc, "", execTime, new Date(), isServer, command.getIsLoop()); + + return (resultState % 2 == 1) ? false : true; + } + + /** + * Agent原生支持命令,Agent自身升级 + * @param params 升级任务的参数 + * @param upgradePath 升级文件存放路径 + * @param stepState 任务执行步骤标志 + * @param curVersion 当前升级版本 + * @param reVersion 恢复到的版本 + * @return + */ + public String upgradeAgent(String param, String upgradePath, long stepState, Long curVersion, Long reVersion) { + logger.info("NC升级开始……"); +// String resultDesc = "执行失败"; +// String resultDesc = "Failure to execute"; + String resultDesc = "i18n_client.AgentCommand.execFail_n81i"; + int resultState = RESULT_FAIL; + File tempUpdateDir = null; + try { + Long curVer = Long.parseLong(VersionCfg + .getValue(VersionCfg.NAGENT_VERSION)); + if (curVer >= curVersion) { +// resultDesc = "执行失败:当前Agent版本为最新"; +// resultDesc = "Execution failure: the current Agent version is the latest"; + resultDesc = "i18n_client.AgentCommand.execFailDesc5_n81i"; + + logger.info("NC升级结果描述信息 >> " + resultDesc); + logger.info("NC升级结束……"); + return resultState + RESULT_SEPRATOR + resultDesc; + } + + /** + * 1、解析命令参数,包装到对象 + */ + logger.debug("upgradeAgent-->param: " + param); + ParamUpgrade cfu = (ParamUpgrade) JSONObject.toBean( + JSONObject.fromObject(param), ParamUpgrade.class); + //Agent的布署路径 + String homePath = new File(Contants.SYSTEM_PATH).getParent(); + /* + * 设置启动文件和PID文件 + */ + String pidFile = Contants.localAgentPidFile; + String startFile = null; + String os = System.getProperty("os.name"); + if (os.startsWith("Windows")) { + startFile = homePath + File.separator + "script" + File.separator + "restart.bat"; + if(!new File(startFile).exists()){ + startFile = Contants.SYSTEM_PATH + File.separator + "restart.bat"; + } + } else if (os.startsWith("Linux")) { + startFile = Contants.SYSTEM_PATH + File.separator + "restart.sh"; + } + cfu.setStartupFile(new File(startFile).getCanonicalPath()); + cfu.setPidFile(new File(pidFile).getCanonicalPath()); + /* + * 处理覆盖目录 + */ + if(cfu.getCover()!=null && !"".equals(cfu.getCover().trim())){ + cfu.setCover(getFilePath(cfu.getCover(), homePath)); + }else{//如果没有参数覆盖目录,则按默认Agent的布署路径 + cfu.setCover(homePath); + } + String backupOppDir = new File(cfu.getCover()).getCanonicalPath(); + + logger.debug("AgentUpgrade homePath----" + homePath); + logger.debug("AgentUpgrade restart file----" + cfu.getStartupFile()); + logger.debug("AgentUpgrade pid file----" + cfu.getPidFile()); + logger.debug("AgentUpgrade cover----" + cfu.getCover()); + + /** + * 步骤2:判断是逆向任务还是正常升级,恢复版本不为空则为逆向任务,反之正常升级 + */ + boolean next = true; + String srcDesc = null; + String destDesc = null; + File upgradeFile = null; + File coverDirFile = null; + if (command.getExecVersion() != null + && command.getExecVersion().longValue() > 0) {//恢复 + if(cfu.getRecoverys()==null || cfu.getRecoverys().length<=0){ +// resultDesc = "执行失败:恢复参数为空"; +// resultDesc = "Execution failure: recovery parameters are empty"; + resultDesc = "i18n_client.AgentCommand.execFailDesc6_n81i"; +// logger.info("NC升级结果描述信息 >> " + resultDesc);//i18nlog + logger.info("NC升级结束……"); + return resultState + RESULT_SEPRATOR + resultDesc; + } + ParamCoverUpdate recover = cfu.getRecoverys()[0]; + cfu.setIsAbs(recover.getIsAbs()); + //文件名称在此没有实际意义,只是为了下面验证时不为空 + cfu.setFileName(getRecoverSource(recover, reVersion)); + //-------必须先处理恢复目录,再处理恢复源文件,恢复源文件会用到恢复目录的名称,否则恢复目录如果是(.)这样的相对路径就会出问题 + //恢复目录若是相对,则相对升级的覆盖目录,若是绝对,则不变 + recover.setCover(getFilePath(recover.getCover(), cfu.getCover())); +// destDesc = "恢复目录"; +// destDesc = "Recovery Directory"; + destDesc = "i18n_client.AgentCommand.destDesc_n81i"; + coverDirFile = new File(recover.getCover()); +// srcDesc = "恢复源文件"; +// srcDesc = "Recovery Source File"; + srcDesc = "i18n_client.AgentCommand.srcDesc_n81i"; + upgradeFile = new File(getRecoverSource(recover, reVersion)); + + logger.debug("AgentUpgrade recover cover----" + recover.getCover()); + } else { + // 处理是否创建覆盖目录 + cfu.setIsCreateCover(handleYesOrNoField(cfu.getIsCreateCover())); +// srcDesc = "升级文件"; +// srcDesc = "Upgrade File"; + srcDesc = "i18n_client.AgentCommand.srcDesc_n81i"; + upgradeFile = new File(getFilePath(cfu.getFileName(), upgradePath)); +// destDesc = "更新目录"; +// destDesc = "Update Table Of Contents"; + destDesc = "i18n_client.AgentCommand.destDesc_n81i"; + coverDirFile = new File(cfu.getCover()); + } + if(coverDirFile.isFile()){ + coverDirFile = coverDirFile.getParentFile(); + } + // 处理解压时按绝对路径,还是相对路径, 只对LInux起作用, 默认按相对 + boolean isAbs = false; + if ("Y".equals(handleYesOrNoField(cfu.getIsAbs()))) { + isAbs = true; + } + /** + * 判断参数指定的升级文件与覆盖目录是否存在 + */ + if (cfu.getFileName() == null + || cfu.getFileName().trim().length() <= 0) { +// resultDesc = "执行失败:" + srcDesc + "为空"; +// resultDesc = "Failure to execute:" + srcDesc + "is empty"; + resultDesc = "i18n_client.AgentCommand.execFail_n81i:" + srcDesc + "i18n_client.AgentCommand.execFailDesc7_n81i"; + resultState = RESULT_FAIL; +// logger.debug(resultDesc);//i18nlog + next = false; + } else if (!upgradeFile.exists()) { +// resultDesc = "执行失败:" + srcDesc + "不存在--" + upgradeFile.getAbsolutePath(); +// resultDesc = "Failure to execute:" + srcDesc + "non-existent--" + upgradeFile.getAbsolutePath(); + resultDesc = "i18n_client.AgentCommand.execFail_n81i:" + srcDesc + "i18n_client.AgentCommand.execFailDesc8_n81i--" + upgradeFile.getAbsolutePath(); + resultState = RESULT_FAIL; +// logger.debug(resultDesc + "--" + upgradeFile.getAbsolutePath());//i18nlog + next = false; + } + // 判断用户和密码是否正确 + /*if (!ProcessUtil.checkUserPass(cfu.getUsername(), cfu.getParam1())) { + resultDesc = "执行失败:用户名或密码不正确;"; + resultState = RESULT_FAIL; + logger.debug(resultDesc); + next = false; + }*/ + // 判断用户名是否正确 + if(!ProcessUtil.checkUserOrGroupExist(cfu.getUsername(), null)){ +// resultDesc = "执行失败:属主不正确;"; +// resultDesc = "Failure of execution: the owner is not correct;"; + resultDesc = "i18n_client.AgentCommand.execFailDesc9_n81i;"; + resultState = RESULT_FAIL; +// logger.debug(resultDesc);//i18nlog + next = false; + } + boolean isCompressFile = false; + if (next) { + /** + * 判断覆盖目录是否存在: + * 1、必须判断:Window系统、或者Linux系统且不是压缩文件、或者Linux系统且是压缩文件且是相对路径 + * 2、不用判断:Linux系统下源文件是压缩文件且绝对解压,该属性无效 + */ + isCompressFile = CompressFileMgr.isCompressFile(upgradeFile); + if (os.startsWith("Windows") + || (!os.startsWith("Windows") && !isCompressFile) + || (!os.startsWith("Windows") && isCompressFile && !isAbs)) { + if (!coverDirFile.exists() + && "N".equalsIgnoreCase(cfu.getIsCreateCover())) { +// resultDesc = "执行失败:" + destDesc + "不存在"; +// resultDesc = "Failure to execute:" + destDesc + "non-existent"; + resultDesc = "i18n_client.AgentCommand.execFail_n81i:" + destDesc + "i18n_client.AgentCommand.execFailDesc8_n81i"; + resultState = RESULT_FAIL; +// logger.debug(resultDesc);//i18nlog + next = false; + } else if (!coverDirFile.exists() + && "Y".equalsIgnoreCase(cfu.getIsCreateCover())) {// Y + // 创建目录 + coverDirFile.mkdirs(); + } + } else { + coverDirFile = new File("/"); + } + } + /** + * 步骤3、对参数指定的备份目录进行备份 + */ + boolean flag = false; + String resultStr = ""; + if (next && (stepState > RESULT_OK && stepState < RESULT_BACKUP_OK)) {// 备份 + Date execTime = new Date(); + resultStr = this.backupCmd(cfu.getBackups(), backupOppDir, curVersion); + String[] res = resultStr.split(RESULT_SEPRATOR_SPLIT); + if (res != null && res.length >= 2) { + resultState = Integer.parseInt(res[0]); + resultDesc = res[1]; + } + if (resultState == RESULT_OK) {// 备份成功,发送信息 + flag = true; + resultState = RESULT_BACKUP_OK; + TaskResultOper.sendTaskResult(command.getExecId(), command + .getExecType(), resultState, resultDesc, "", + execTime, new Date(), false, command.getIsLoop()); + } else { + flag = false; + } + + } + + /** + * 步骤4、覆盖并重启Agent + */ + if (next && flag) {// 解压成功,覆盖并重启Agent + Date execTime = new Date(); + + /** + * 4-1 发送重启请求 + */ + TaskResultOper.sendTaskResult(command.getExecId(), command +// .getExecType(), resultState, "正在覆盖并重启Agent", "", +// .getExecType(), resultState, "Overlaying and restarting Agent", "", + .getExecType(), resultState, "i18n_client.AgentCommand.coverRestart_n81i", "", + execTime, new Date(), false, command.getIsLoop()); + + // 判断是否解压升级文件,并放入临时目录 + tempUpdateDir = new File(Contants.localTempPath + File.separator + + "agent_updatedir_" + command.getExecId()); + if (upgradeFile.isDirectory()) { + FileUtils.copyDirectoryToDirectory(upgradeFile, tempUpdateDir); + } else { + if (isCompressFile) { + flag = new CompressFileMgr().decompressFile( + upgradeFile.getAbsolutePath(), tempUpdateDir + .getAbsolutePath(), false); + } else { + FileUtils.copyFileToDirectory(upgradeFile,tempUpdateDir); + } + } + + /** + * 4-2 删除文件,并写临时结果文件 + */ + //准备临时结果文件内容,初始状态为升级失败 + String[] msgs = new String[1]; + msgs[0] = TaskResultOper.getTaskResultMsg(command + .getExecId(), command.getExecType(), +// (long) RESULT_FAIL, "升级失败", "", execTime, new Date(), command.getIsLoop()); +// (long) RESULT_FAIL, "Failure to upgrade", "", execTime, new Date(), command.getIsLoop()); + (long) RESULT_FAIL, "i18n_client.AgentCommand.upgradeFail_n81i", "", execTime, new Date(), command.getIsLoop()); + File resultFile = new File(TaskResultOper + .getAgentUpgradeResultTempFile(command.getExecType(), + command.getExecId())); + if(!resultFile.getParentFile().exists()){ + resultFile.getParentFile().mkdirs(); + } + // 删除指定的文件 + String delMsg = this.delete(cfu.getDelete(), coverDirFile.getAbsolutePath()); + // 将删除日志换行加入结果文件 + if(!StringUtils.isEmpty(delMsg)){ + msgs = new String[]{msgs[0], delMsg}; + } + // 正式写入临时结果文件 + FileWrUtil.cfgFilePrinter(resultFile, Charset.defaultCharset().name(), msgs); + + /** + * 4-3 执行脚本(脚本中将覆盖操作的详细信息追加到结果文件;覆盖成功后将任务标识ID写入version.txt) + */ + List startList = new ArrayList(); + ParamCmdExec exec = new ParamCmdExec(); + exec.setExecCmd(cfu.getStartupFile()); + exec.setExecParams(new String[] { tempUpdateDir.getCanonicalPath(), + coverDirFile.getCanonicalPath(), + resultFile.getCanonicalPath() }); + exec.setExecResult(cfu.getPidFile()); + exec.setUsername(cfu.getUsername()); + exec.setParam1(cfu.getParam1()); + exec.setForceExec("Y"); + exec.setResidentFlag("Y"); + exec.setReturnFlag("N"); + startList.add(exec); + resultStr = this.startCmd(startList, execTime, true, resultState); + String[] res = resultStr.split(RESULT_SEPRATOR_SPLIT); + if (res != null && res.length >= 2) { + resultState = Integer.parseInt(res[0]); + resultDesc = res[1]; + } + if (resultState == RESULT_FAIL && resultFile.exists()) {// 如果失败直接返回结果,删除临时结果文件 + //resultFile.delete_bak(); + //使用删除文件公共方法 + FileUtil.delDir(resultFile); + logger.debug("upgradeAgent delete file -- " + resultFile.getAbsolutePath()); + //FileUtil.checkParentDirExist(resultFile); + } + } else { + if (stepState == RESULT_BACKUP_OK) { +// resultDesc = "重启失败,手工启动成功"; +// resultDesc = "Restart failure and start success by hand"; + resultDesc = "i18n_client.AgentCommand.restartFail_n81i"; + resultState = RESULT_FAIL; + String upgradeResultFile = TaskResultOper + .getAgentUpgradeResultTempFile(command + .getExecType(), command.getExecId()); + File resultFile = new File(upgradeResultFile); + if (resultFile.exists()) {// 如果失败直接返回结果,删除临时结果文件 + //resultFile.delete_bak(); + //使用删除文件公共方法 + FileUtil.delDir(resultFile); + logger.debug("upgradeAgent delete file 2 -- " + resultFile.getAbsolutePath()); + //FileUtil.checkParentDirExist(resultFile); + } + } + + } + } catch (Exception e) { +// resultDesc = "执行失败:出现异常," + e.getMessage() + ",详细信息请查看日志"; + resultDesc = "i18n_client.AgentCommand.execFailDesc10_n81i," + e.getMessage() + ",i18n_client.AgentCommand.execFailDesc10.showDetail_n81i"; + resultState = RESULT_FAIL; + logger.error("NC upgrade exception:" + Utils.printExceptionStack(e)); + } finally { + // 不能删除临时目录原因:覆盖操作在脚本中进行,可能出现脚本未运行完,临时目录被删除,这样覆盖操作就不能完成 + /*if(tempUpdateDir!=null && tempUpdateDir.exists()){ + try { + FileUtils.deleteDirectory(tempUpdateDir); + logger.debug("upgradeAgentNew-----finally delele tempUpdateDir = " + tempUpdateDir.getCanonicalPath()); + FileUtil.checkParentDirExist(tempUpdateDir); + } catch (IOException e) { + } + }*/ + } +// logger.info("NC升级结果描述信息 >> " + resultDesc);//i18nlog + logger.info("NC升级结束……"); + + return resultState + RESULT_SEPRATOR + resultDesc; + } + + /** + * Agent原生支持命令,第三方升级 + * @param params 升级任务的参数 + * @param upgradePath 升级文件存放目录 + * @param stepState 任务执行步骤标志 + * @param curVersion 当前升级版本 + * @param reVersion 恢复到的版本,如果是逆向任务即恢复时用到 + * @param isServer 是否NmsServer升级 + * @return + */ + public String upgradeOther(String[] params, String upgradePath, long stepState, long curVersion, Long reVersion, boolean isServer) { +// String pre = "三方升级"; + String pre = "Three Party Upgrade"; + if (isServer) {// 如果是NmsServer升级,判断版本 +// pre = "DC升级"; + pre = "DC Upgrade"; + } + logger.info(pre + "开始……"); +// String resultDesc = "执行失败"; + String resultDesc = "Failure to execute"; + int resultState = RESULT_FAIL; + try { + if(params==null || params.length==0){ +// resultDesc = "执行失败:参数为空"; +// resultDesc = "Execution failure: parameters are empty"; + resultDesc = "i18n_client.AgentCommand.execFailDesc11_n81i"; +// logger.info(pre + "结果描述信息 >> " + resultDesc);//i18nlog + logger.info(pre + "结束……"); + return resultState + RESULT_SEPRATOR + resultDesc; + } + if (isServer) {// 如果是NmsServer升级,判断版本 + Long curVer = Long.parseLong(VersionCfg + .getValue(VersionCfg.NSERVER_VERSION)); + if (curVer >= curVersion) { +// resultDesc = "执行失败:当前Server版本为最新"; +// resultDesc = "Execution failure: the current Server version is the latest"; + resultDesc = "i18n_client.AgentCommand.execFailDesc12_n81i"; +// logger.info(pre + "结果描述信息 >> " + resultDesc);//i18nlog + logger.info(pre + "结束……"); + return resultState + RESULT_SEPRATOR + resultDesc; + } + + } + /** + * 1、解析命令参数,包装到对象, 判断是否为逆向任务: + * 不是,判断所有参数指定的升级文件与覆盖目录是否存在; + * 是,设置默认强制执行并跳过判断 + */ + boolean next = true; + List cfuList = new ArrayList(); + for (String param : params) { + if (param.trim().length() <= 0) { + continue; + } + logger.debug("upgradeOther-->param: " + param); + ParamUpgrade cfu = (ParamUpgrade) JSONObject.toBean(JSONObject + .fromObject(param), ParamUpgrade.class); + logger.debug("upgradeOther-->pidFile: " + cfu.getPidFile()); + + // 判断用户和密码是否正确 + /*if (!ProcessUtil.checkUserPass(cfu.getUsername(), cfu.getParam1())) { + resultDesc = "执行失败:用户名或密码不正确;"; + resultState = RESULT_FAIL; + logger.debug(resultDesc); + next = false; + break; + }*/ + // 判断用户名是否正确 + if(!ProcessUtil.checkUserOrGroupExist(cfu.getUsername(), null)){ +// resultDesc = "执行失败:属主不正确;"; +// resultDesc = "Failure of execution: the owner is not correct;"; + resultDesc = "i18n_client.AgentCommand.execFailDesc13_n81i;"; + resultState = RESULT_FAIL; +// logger.debug(resultDesc);//i18nlog + next = false; + } + + // 恢复版本不为空则为逆向任务 + if (reVersion != null && reVersion.longValue() > 0) {// 恢复 + cfuList.add(cfu); + continue; + } + + cfu.setIsCreateCover(handleYesOrNoField(cfu.getIsCreateCover())); + // 处理解压时按绝对路径,还是相对路径, 只对LInux起作用, 默认按相对 + boolean isAbs = false; + if ("Y".equals(handleYesOrNoField(cfu.getIsAbs()))) { + isAbs = true; + } + /** + * 判断升级文件是否存在 + */ + if (cfu.getFileName() == null + || cfu.getFileName().trim().length() <= 0) { +// resultDesc = "执行失败:升级文件名为空"; +// resultDesc = "Execution failure: the upgrade file name is empty"; + resultDesc = "i18n_client.AgentCommand.execFailDesc14_n81i"; + resultState = RESULT_FAIL; +// logger.debug(resultDesc);//i18nlog + next = false; + break; + } + File upgradeFile = new File(getFilePath(cfu.getFileName(), + upgradePath)); + if (!upgradeFile.exists()) { +// resultDesc = "执行失败:升级文件“" + cfu.getFileName() + "”不存在--" +// resultDesc = "Execution failure: upgrade file“" + cfu.getFileName() + "”non-existent--" + resultDesc = "i18n_client.AgentCommand.execFailDesc15_n81i“" + cfu.getFileName() + "”i18n_client.AgentCommand.execFailDesc8_n81i--" + + upgradeFile.getAbsolutePath(); + resultState = RESULT_FAIL; +// logger.debug(resultDesc);//i18nlog + next = false; + break; + } + /** + * 判断覆盖目录是否存在: + * 1、必须判断:Window系统、或者Linux系统且不是压缩文件、或者Linux系统且是压缩文件且是相对路径 + * 2、不用判断:Linux系统下源文件是压缩文件且绝对解压,该属性无效 + */ + File coverDirFile = null; + boolean isCompressFile = CompressFileMgr.isCompressFile(upgradeFile); + String os = System.getProperty("os.name"); + if (os.startsWith("Windows") + || (!os.startsWith("Windows") && !isCompressFile) + || (!os.startsWith("Windows") && isCompressFile && !isAbs)) { + if (cfu.getCover() == null + || cfu.getCover().trim().length() <= 0) { +// resultDesc = "执行失败:覆盖目录为空"; +// resultDesc = "Execution failure: overlay the directory to be empty"; + resultDesc = "i18n_client.AgentCommand.execFailDesc16_n81i"; + resultState = RESULT_FAIL; +// logger.debug(resultDesc);//i18nlog + next = false; + break; + } + coverDirFile = new File(cfu.getCover()); + if (!coverDirFile.exists() + && "N".equalsIgnoreCase(cfu.getIsCreateCover())) { +// resultDesc = "执行失败:覆盖目录不存在--" +// resultDesc = "Execution failure: the overlay directory does not exist--" + resultDesc = "i18n_client.AgentCommand.execFailDesc17_n81i--" + + coverDirFile.getAbsolutePath(); + resultState = RESULT_FAIL; +// logger.debug(resultDesc);//i18nlog + next = false; + break; + } + // Y 创建目录 + if (!coverDirFile.exists()) { + coverDirFile.mkdirs(); + } + } else { + coverDirFile = new File("/"); + } + + cfuList.add(cfu); + } + /** + * 步骤2、停用所有进程,所有对象同步进行,有一个失败则失败 + */ + String resultStr = ""; + boolean flag = false; + if (next && (stepState > RESULT_OK && stepState < RESULT_KILL_OK)) { + String temp = ""; + if (isServer) {// 如果是NmsServer升级,发送升级请求 + for (int i = 0; i < Contants.max_times; i++) {// 失败,尝试几次 + Future future = Common.service + .submit(new SSLClient(Thread.currentThread().getName() + " >> DC升级请求", + CommonSocket.REQ_SERVER_UPGRADE, + null, Utils.getLocalIp())); + String msg = (String) future.get(); + temp = Contants.getDescByResult(msg); + if(Contants.isSucessByResult(msg)){ + break; + } + try {// 如果更新失败,让当前线程暂停几秒,再重试 + Thread.sleep(1000 * Contants.max_delay_seconds); + } catch (InterruptedException e) { + logger.error(Utils.printExceptionStack(e)); + continue; + } + } +// temp = "DC升级请求" + ((temp!=null && temp.trim().length()>0) ? temp : "失败") + ";"; +// temp = "DC upgrade request" + ((temp!=null && temp.trim().length()>0) ? temp : "失败") + ";"; + temp = "i18n_client.AgentCommand.DCupdate_n81i" + ((temp!=null && temp.trim().length()>0) ? temp : "i18n_client.AgentCommand.fail_n81i") + ";"; + } + + Date execTime = new Date(); + String[] pidArr = new String[cfuList.size()]; + int i = 0; + for(ParamUpgrade cfu:cfuList){ + pidArr[i++] = cfu.getPidFile(); + } + resultStr = this.killProcessCmd(pidArr); + String[] res = resultStr.split(RESULT_SEPRATOR_SPLIT); + if (res != null && res.length >= 2) { + resultState = Integer.parseInt(res[0]); + resultDesc = temp + res[1]; + } + if(resultState == RESULT_OK){ + flag = true; + resultState = RESULT_KILL_OK; + // 发送信息 + TaskResultOper.sendTaskResult(command.getExecId(), command.getExecType(), + resultState, resultDesc, "", execTime, new Date(), isServer, command.getIsLoop()); + }else{ + flag = false; + } + } + /** + * 步骤3、对所有参数指定的备份目录进行备份,有一个失败则失败 + */ + if (next && (flag || stepState == RESULT_KILL_OK)) {// 停用进程成功,再进行备份 + Date execTime = new Date(); + StringBuffer sb = new StringBuffer(); + for(ParamUpgrade cfu:cfuList){ + resultStr = this.backupCmd(cfu.getBackups(), cfu.getCover(), curVersion); + String[] res = resultStr.split(RESULT_SEPRATOR_SPLIT); + if (res != null && res.length >= 2) { + resultState = Integer.parseInt(res[0]); + sb.append(res[1] + ";"); + } + if(resultState == RESULT_FAIL){ + break; + } + } + resultDesc = sb.toString(); + if(resultState == RESULT_OK){ + flag = true; + resultState = RESULT_BACKUP_OK; + // 发送信息 + TaskResultOper.sendTaskResult(command.getExecId(), command.getExecType(), + resultState, resultDesc, "", execTime, new Date(), isServer, command.getIsLoop()); + }else{ + flag = false; + } + } + /** + * 步骤4、对所有参数指定的覆盖目录进行更新并删除指定的文件,有一个失败则失败 + */ + if (next && (flag || stepState == RESULT_BACKUP_OK)) {// 备份成功,再进行覆盖即更新 + Date execTime = new Date(); + ParamCoverUpdate[] updates = handleCoverUpdates(cfuList, reVersion, upgradePath); + for (int i = 0; i < Contants.max_times; i++) { + resultStr = this.updateCmd(updates); + String[] res = resultStr.split(RESULT_SEPRATOR_SPLIT); + if (res != null && res.length >= 2) { + resultState = Integer.parseInt(res[0]); + resultDesc = res[1]; + } + if (resultState == RESULT_OK) { + break; + } + try {// 如果更新失败,让当前线程暂停几秒,再重试 + Thread.sleep(1000 * Contants.max_delay_seconds); + } catch (InterruptedException e) { + logger.error(Utils.printExceptionStack(e)); + continue; + } + } + if (resultState == RESULT_OK) { + flag = true; + resultState = RESULT_UPDATE_OK; + // 发送信息 + TaskResultOper.sendTaskResult(command.getExecId(), command.getExecType(), + resultState, resultDesc, "", execTime, new Date(), isServer, command.getIsLoop()); + }else{ + flag = false; + } + if(flag && isServer){ + Long curVer = Long.parseLong(VersionCfg + .getValue(VersionCfg.NSERVER_VERSION)); + if (curVer < curVersion) { + VersionCfg.setValue(VersionCfg.NSERVER_VERSION, curVersion + ""); + logger.info("DC升级到版本" + curVersion); + } + } + } + /** + * 步骤5、顺序启动所有进程,有一个失败则失败 + */ + if (next && (flag || stepState == RESULT_UPDATE_OK)) {// 更新成功,再启动进程 + Date execTime = new Date(); + List startList = new ArrayList(); + for(ParamUpgrade cfu:cfuList){ + ParamCmdExec exec = new ParamCmdExec(); + exec.setExecCmd(cfu.getStartupFile()); + exec.setExecParams(cfu.getExecParams()); + exec.setExecResult(cfu.getPidFile()); + exec.setMaxWaitTime(cfu.getMaxWaitTime()); + exec.setUsername(cfu.getUsername()); + exec.setParam1(cfu.getParam1()); + exec.setForceExec("Y"); + exec.setResidentFlag("Y"); + exec.setReturnFlag("N"); + startList.add(exec); + } + resultStr = this.startCmd(startList, execTime, false, resultState); + String[] res = resultStr.split(RESULT_SEPRATOR_SPLIT); + if (res != null && res.length >= 2) { + resultState = Integer.parseInt(res[0]); + resultDesc = res[1]; + } + } + } catch (Exception e) { +// resultDesc = "执行失败:出现异常," + e.getMessage() + ",详细信息请查看日志"; +// resultDesc = "Execution failure: abnormality," + e.getMessage() + ",please check the log for details"; + resultDesc = "i18n_client.AgentCommand.execFailDesc18_n81i," + e.getMessage() + ",i18n_client.AgentCommand.execFailDesc10.showDetail_n81i"; + resultState = RESULT_FAIL; + logger.error(pre + "anormly:" + Utils.printExceptionStack(e)); + }finally{ + } +// logger.info(pre + "结果描述信息 >> " + resultDesc);//i18nlog + logger.info(pre + "结束……"); + + return resultState + RESULT_SEPRATOR + resultDesc; + } + + /** + * Agent原生支持命令,备份 + * @param backups 备份文件包装对象数组(需要备份的目录、备份到的目录、排除的目录) + * @param version + * @return + */ + public String backupCmd(ParamBackup[] backups, String oppositeBackupDir, Long version){ + logger.info("备份开始……"); + String resultDesc = ""; + long resultState = RESULT_FAIL; + try { + if(backups==null || backups.length<=0){ +// resultDesc = "备份成功:未指定备份参数,不需要备份"; +// resultDesc = "Backup success: no backup parameters specified, no backup required"; + resultDesc = "i18n_client.AgentCommand.backupSuccess1_n81i"; + resultState = RESULT_OK; +// logger.debug(resultDesc);//i18nlog + }else{ + StringBuffer sb = new StringBuffer(); + CompressFileMgr cfmImpl = new CompressFileMgr(); + for(int i=0; ioppositeBackupDir=" + oppositeBackupDir); + if(oppositeBackupDir!=null && oppositeBackupDir.trim().length()>0){ + backup.setBackup(getFilePath(backup.getBackup(), oppositeBackupDir)); + } + // 判断需要备份的文件是否存在 + String backupPath = backup.getBackup(); + if(backup.getBackup()==null || backup.getBackup().trim().length()<=0){ +// resultDesc = "备份失败,需要备份的文件属性为空"; +// resultDesc = "Backup failed, the file property that needs to be backed up is empty"; + resultDesc = "i18n_client.AgentCommand.backupFail1_n81i"; + sb.append(resultDesc + ";"); + resultState = RESULT_FAIL; +// logger.debug(resultDesc);//i18nlog + break; + } + File srcFile = new File(backup.getBackup().trim()); + if(!srcFile.exists()){ +// resultDesc = "备份“" + backupPath + "”失败,需要备份的文件不存在--" + srcFile.getAbsolutePath(); +// resultDesc = "Backup“" + backupPath + "” failed, the file that needs to be backed up does not exist--" + srcFile.getAbsolutePath(); + resultDesc = "i18n_client.AgentCommand.backup_n81i“" + backupPath + "” i18n_client.AgentCommand.backupFail2_n81i--" + srcFile.getAbsolutePath(); + sb.append(resultDesc + ";"); + resultState = RESULT_FAIL; +// logger.debug(resultDesc);//i18nlog + break; + }else if(srcFile.isDirectory() && srcFile.list().length<=0){ +// resultDesc = "备份“" + backupPath + "”成功,需要备份的文件目录为空,不用进行备份"; +// resultDesc = "Backup“" + backupPath + "”successful, the backup file directory is empty without backup"; + resultDesc = "i18n_client.AgentCommand.backup_n81i“" + backupPath + "”i18n_client.AgentCommand.backupSuccess2_n81i"; + sb.append(resultDesc + ";"); + resultState = RESULT_OK; +// logger.debug(resultDesc);//i18nlog + continue; + } + // 处理压缩时按绝对路径,还是相对路径, 只对LInux起作用, 默认按相对 + boolean isAbs = false; + if("Y".equals(handleYesOrNoField(backup.getIsAbs()))){ + isAbs = true; + } + // 处理备份到的目录 + if(backup.getBackupTo()==null || backup.getBackupTo().trim().length()<=0){ + backup.setBackupTo(Contants.localBackupPath); + }else{ + backup.setBackupTo(Contants.localBackupPath + + File.separator + backup.getBackupTo().trim()); + } + // 处理备份操作 + String compressName = backup.getBackupTo() + File.separator + + getBakFileName(srcFile.getName(), version, isAbs); + File destDirFile = new File(compressName); + if (!destDirFile.exists()) { + if (!destDirFile.getParentFile().exists()) { + destDirFile.getParentFile().mkdirs(); + } + if (destDirFile.getParentFile().canWrite()) { + String[] excepts = backup.getExcept(); + if(excepts!=null && excepts.length>0){ + for(int j=0; j0){ + excepts[j] = getFilePath(excepts[j], backup.getBackup()); + } + } + } + boolean flag = cfmImpl.compressFile(srcFile.getAbsolutePath(), destDirFile.getAbsolutePath(), excepts, isAbs); + +// resultDesc = flag ? "备份“" + backupPath +// + "”成功,备份文件" + destDirFile.getAbsolutePath() +// : "备份“" + backupPath + "”失败"; + resultDesc = flag ? "i18n_client.AgentCommand.backup_n81i“" + backupPath + + "”i18n_client.AgentCommand.backupSuccess3_n81i" + destDirFile.getAbsolutePath() + : "i18n_client.AgentCommand.backup_n81i“" + backupPath + "”i18n_client.AgentCommand.backupFail3_n81i"; + sb.append(resultDesc + ";"); + resultState = flag ? RESULT_OK : RESULT_FAIL; + logger.debug(resultDesc + ": " +// + srcFile.getAbsolutePath() + " 到 " + + srcFile.getAbsolutePath() + " to " + + destDirFile.getAbsolutePath()); + if (resultState == RESULT_FAIL) { + break; + } + }else{ +// resultDesc = "备份“" + backupPath + "”失败,备份到的目录”" + backup.getBackupTo() + "“只读"; +// resultDesc = "Backup“" + backupPath + "”failed, backup to the directory”" + backup.getBackupTo() + "“read-only"; + resultDesc = "i18n_client.AgentCommand.backup_n81i“" + backupPath + "”i18n_client.AgentCommand.backupFail4_n81i”" + backup.getBackupTo() + "“i18n_client.AgentCommand.readonly_n81i"; + sb.append(resultDesc + ";"); + resultState = RESULT_FAIL; +// logger.debug(resultDesc + "--" + destDirFile.getParent());//i18nlog + break; + } + }else{ +// resultDesc = "备份“" + backupPath + "”成功,已存在该版本备份,不用备份--备份文件" + destDirFile.getAbsolutePath(); +// resultDesc = "Backup“" + backupPath + "”Successful version already exists, without backup - backup files" + destDirFile.getAbsolutePath(); + resultDesc = "i18n_client.AgentCommand.backup_n81i“" + backupPath + "”i18n_client.AgentCommand.backupSuccess4_n81i" + destDirFile.getAbsolutePath(); + sb.append(resultDesc + ";"); + resultState = RESULT_OK; +// logger.debug(resultDesc + "--" + destDirFile.getAbsolutePath());//i18nlog + } + }//for end +// resultDesc = resultState==RESULT_OK ? "备份成功,详情信息如下:" + sb.toString() : "备份失败,详情信息如下:" + sb.toString(); +// resultDesc = resultState==RESULT_OK ? "The backup is successful, and the details are as follows:" + sb.toString() : "Backup failed, the details are as follows:" + sb.toString(); + resultDesc = resultState==RESULT_OK ? "i18n_client.AgentCommand.backupSuccess5_n81i:" + sb.toString() : "i18n_client.AgentCommand.backupFail5_n81i:" + sb.toString(); + } + } catch (Exception e) { +// resultDesc = "备份失败:出现异常," + e.getMessage() + ",详细信息请查看日志"; +// resultDesc = "Backup failure: Exception," + e.getMessage() + ",please check the log for details"; + resultDesc = "i18n_client.AgentCommand.backupFail6_n81i," + e.getMessage() + ",i18n_client.AgentCommand.execFailDesc10.showDetail_n81i"; + resultState = RESULT_FAIL; + logger.error("备份异常:" + Utils.printExceptionStack(e)); + } +// logger.info("备份结果描述信息 >> " + resultDesc);//i18nlog + logger.info("备份结束……"); + + return resultState + RESULT_SEPRATOR + resultDesc; + } + + /** + * Agent原生支持命令,覆盖更新或恢复 + * @param updates 覆盖更新包装对象数组(备份的文件、恢复的目录、删除的文件或目录) + * @return + */ + public String updateCmd(ParamCoverUpdate[] updates){ + logger.info("更新或恢复开始……"); + String resultDesc = ""; + long resultState = RESULT_FAIL; + try { + if(updates==null || updates.length<=0){ +// resultDesc = "覆盖成功:未指定参数,不需要覆盖"; +// resultDesc = "Overwrite success: unspecified parameters, no need to cover"; + resultDesc = "i18n_client.AgentCommand.coverSuccess1_n81i"; + resultState = RESULT_OK; +// logger.debug(resultDesc);//i18nlog + } else { + StringBuffer sb = new StringBuffer(); + CompressFileMgr cfmImpl = new CompressFileMgr(); + for(int i=0; i> " + resultDesc);//i18nlog + logger.info("更新或恢复结束……"); + + return resultState + RESULT_SEPRATOR + resultDesc; + } + + /** + * Agent原生支持命令,停用进程 + * @param pidFileArr 存放进程ID的文件的数组集 + * @return + */ + public String killProcessCmd(String[] pidFileArr) { + logger.info("停用进程集开始……"); + String resultDesc = ""; + long resultState = RESULT_FAIL; + + try { + if(pidFileArr==null || pidFileArr.length<=0){ +// resultDesc = "停用进程失败:未指定PID文件参数"; +// resultDesc = "Deactivation process failed: PID file parameter not specified"; + resultDesc = "i18n_client.AgentCommand.killProcFail1_n81i"; + resultState = RESULT_FAIL; +// logger.debug(resultDesc);//i18nlog + }else { + StringBuffer sb = new StringBuffer(); + for(String pidFileStr : pidFileArr){ + logger.debug("upgradeKillProcess pidFile------->" + pidFileStr); + File pidFile = new File(pidFileStr); + if(pidFileStr==null || pidFileStr.trim().length()<=0){ + resultState = RESULT_OK; +// resultDesc = "停用成功,进程PID文件为空"; +// resultDesc = "Disabled, process PID file is empty"; + resultDesc = "i18n_client.AgentCommand.killProcSuccess1_n81i"; + sb.append(resultDesc + ";"); +// logger.debug(resultDesc + "--" + pidFile.getAbsolutePath() );//i18nlog + }else if(!pidFile.exists()){ + resultState = RESULT_OK; +// resultDesc = "停用“" + pidFileStr + "”成功,进程PID文件找不到"; + resultDesc = "i18n_client.AgentCommand.deactivate_n81i“" + pidFileStr + "”i18n_client.AgentCommand.killProcSuccess2_n81i"; + sb.append(resultDesc + ";"); +// logger.debug(resultDesc + "--" + pidFile.getAbsolutePath() );//i18nlog + } else { + String[] pidArr = ProcessUtil.getProcessIdByFile(pidFile); + boolean isExist = false; + if (pidArr != null && pidArr.length > 0) { + for (int i = 0; i < pidArr.length; i++) {// 目前考虑只有一个PID的情况 + isExist = ProcessUtil + .isProcessExistByPid(pidArr[i]); + if (isExist) {// 只要有一个PID存在,就认为是进程存在 + break; + } + } + } + if (!isExist) { +// resultDesc = "停用“" + pidFileStr + "”成功:进程原本不存在"; +// resultDesc = "Deactivate“" + pidFileStr + "”Success: Process does not exist originally"; + resultDesc = "i18n_client.AgentCommand.deactivate_n81i“" + pidFileStr + "”i18n_client.AgentCommand.killProcSuccess3_n81i"; + sb.append(resultDesc + ";"); + resultState = RESULT_OK; +// logger.debug(resultDesc);//i18nlog + } else { + for (int i = 0; i < pidArr.length; i++) { + ProcessUtil.killProcess(pidArr[i]);// 杀进程 + } + for (int i = 0; i < Contants.max_times; i++) { + pidArr = ProcessUtil.getProcessIdByFile(new File(pidFileStr)); + isExist = false; + if (pidArr != null && pidArr.length > 0) { + for (int j = 0; j < pidArr.length; j++) { + isExist = ProcessUtil + .isProcessExistByPid(pidArr[j]); + if (isExist) {// 只要有一个PID存在,就认为是停用进程失败 + break; + } + } + } + if (!isExist) { + break; + } + try {// 如果停用进程失败,让当前线程暂停几秒,再重试 + Thread + .sleep(1000 * Contants.max_delay_seconds); + } catch (InterruptedException e) { + logger.error(Utils.printExceptionStack(e)); + continue; + } + } + resultState = !isExist ? RESULT_OK : RESULT_FAIL; +// resultDesc = !isExist ? "停用“" + pidFileStr + "”成功" +// : "停用“" + pidFileStr +// + "”失败, 进程存在,请查看是否有守护进程"; +// resultDesc = !isExist ? "Deactivation of“" + pidFileStr + "”succeeded" +// : "Deactivate“" + pidFileStr +// + "”Failed, process exists, see if there is a daemon"; + resultDesc = !isExist ? "i18n_client.AgentCommand.deactivate_n81i“" + pidFileStr + "”i18n_client.AgentCommand.killProcSuccess4_n81i" + : "i18n_client.AgentCommand.deactivate_n81i“" + pidFileStr + + "”i18n_client.AgentCommand.killProcFail2_n81i"; + sb.append(resultDesc + ";"); +// logger.debug(resultDesc);//i18nlog + if (resultState == RESULT_FAIL) { + break; + } + } + } + + }//for end +// resultDesc = resultState == RESULT_OK ? "停用进程成功,详情信息如下:" + sb.toString() : "停用进程失败,详情信息如下:" + sb.toString(); +// resultDesc = resultState == RESULT_OK ? "Deactivation process is successful. Details are as follows:" + sb.toString() : "Deactivation process failed, details are as follows:" + sb.toString(); + resultDesc = resultState == RESULT_OK ? "i18n_client.AgentCommand.killProcSuccess5_n81i:" + sb.toString() : "i18n_client.AgentCommand.killProcFail3_n81i:" + sb.toString(); + } + } catch (Exception e) { +// resultDesc = "停用进程失败:出现异常," + e.getMessage() + ",详细信息请查看日志"; + resultDesc = "i18n_client.AgentCommand.killProcFail4_n81i," + e.getMessage() + ",i18n_client.AgentCommand.execFailDesc10.showDetail_n81i"; + resultState = RESULT_FAIL; + logger.error("Disable process set exception:" + Utils.printExceptionStack(e)); + } +// logger.info("停用进程集结果描述信息 >> " + resultDesc);//i18nlog + logger.info("停用进程集结束……"); + + return resultState + RESULT_SEPRATOR + resultDesc; + } + + /** + * Agent原生支持命令,启动进程 + * @param execList 命令参数对象集 + * @param isRestart 当前运行的文件或命令,是否是重新启动,若是则不用判断进程是否存在,直接执行 + * @return + */ + public String startCmd(List execList, Date startTime, boolean isRestart, long stepState){ + logger.info("启动开始……"); + String resultDesc = ""; + StringBuffer sb = new StringBuffer(); + long resultState = RESULT_FAIL; + try { + if(execList==null || execList.size()<=0){ +// resultDesc = "执行成功:未指定内容,不需要执行"; +// resultDesc = "Execution success: unspecified content, no need to execute"; + resultDesc = "i18n_client.AgentCommand.startCmdSuccess1_n81i"; + resultState = RESULT_OK; + logger.debug(resultDesc); + } else { + List returnFileList = new ArrayList(); + + for(ParamCmdExec exec : execList){ + if (stepState != RESULT_START_OK + && stepState != RESULT_START_FAIL) {// 若还未执行过,则继续执行,否则,只进行回传文件 + /** + * 步骤1、判断执行文件是否存在且可执行 + */ + if(exec.getExecCmd()==null || exec.getExecCmd().trim().length()<=0){ +// sb.append("执行“" + exec.getExecCmd() + "”失败,执行命令为空;"); +// sb.append("Execute“" + exec.getExecCmd() + "”Failure, the result file is empty;"); + sb.append("i18n_client.AgentCommand.exec_n81i“" + exec.getExecCmd() + "”i18n_client.AgentCommand.startCmdFail1_n81i;"); + resultState = RESULT_FAIL; + break; + } + if(exec.getExecResult()==null || exec.getExecResult().trim().length()<=0){ +// sb.append("执行“" + exec.getExecCmd() + "”失败,结果文件为空;"); +// sb.append("Execute“" + exec.getExecCmd() + "”Failure, the result file is empty;"); + sb.append("i18n_client.AgentCommand.exec_n81i“" + exec.getExecCmd() + "”i18n_client.AgentCommand.startCmdFail2_n81i;"); + resultState = RESULT_FAIL; + break; + } + // 2013-4-26 由于DC改为Windows服务后升级要支持命令,若命令复杂的话,无法正确判断,做不作此步判断,待以后确定执行方案后考虑此步要不要 + /*boolean existFlag= ProcessUtil.isFileOrCmdExist(exec.getExecCmd()); + if(!existFlag){ + sb.append("执行“" + exec.getExecCmd() + "”失败,执行文件不存在或不是可执行命令;"); + resultState = RESULT_FAIL; + break; + }*/ + // 判断用户和密码是否正确 + /*boolean flag = ProcessUtil.checkUserPass(exec.getUsername(), exec.getParam1()); + if (!flag) { + sb.append("执行“" + exec.getExecCmd() + "”失败,用户名或密码不正确;"); + resultState = RESULT_FAIL; + break; + }*/ + // 判断用户名是否正确 + if(!ProcessUtil.checkUserOrGroupExist(exec.getUsername(), null)){ +// sb.append("执行“" + exec.getExecCmd() + "”失败,用户名不正确;"); +// sb.append("Execute“" + exec.getExecCmd() + "”Failure, incorrect username"); + sb.append("i18n_client.AgentCommand.exec_n81i“" + exec.getExecCmd() + "”i18n_client.AgentCommand.startCmdFail3_n81i"); + resultState = RESULT_FAIL; + break; + } + //判断用户是否有执行命令的权限 + //------------待完成su - -c "[ -x jzz_test.py ];echo $?" nmstest; + /** + * 步骤2、判断是否常驻内存 + * (1) 常驻内存,判断进程是否存在,是否强制执行; + * (2) 非常驻内存,直接执行 + */ + boolean residentFlag = false; + if ("Y".equals(handleYesOrNoField(exec.getResidentFlag()))) { + residentFlag = true; + } + // 如果不是重启操作,则判断进程是否存在,反之,不判断进程是否存在,直接进行下面的执行部分 + if (residentFlag && !isRestart) {//----常驻内存,针对PID判断操作,execResult存放PID的文件 + //----步骤2-1-0、判断进程是否存在: 先判断进程PID文件是否存在--不存在认为进程不存在,存在判断进程PID是否存在 + File pidFile = new File(exec.getExecResult()); + boolean isExist = false; + String[] pidArr = null; + if(pidFile.exists()){ + pidArr = ProcessUtil.getProcessIdByFile(pidFile); + if (pidArr != null) { + for(int i=0; i0){ + synchronized (this) { + logger.debug("wait: " + delay + " seconds"); + this.wait(delay * 1000); + } + } + // -------------步骤3-1、判断进程启动成功与否 + if (residentFlag) {// ---常驻内存,针对PID判断操作 + File pidFile = new File(exec.getExecResult()); + boolean isExist = false; + if (pidFile.exists()) { + String[] pidArr = ProcessUtil.getProcessIdByFile(pidFile); + isExist = false; + String notExitPids = null; + if (pidArr != null) { + for (int i = 0; i < pidArr.length; i++) { + isExist = ProcessUtil.isProcessExistByPid(pidArr[i]); + if (!isExist) {// 如果有一个PID不存在,就认为启动不成功 + notExitPids = pidArr[i]; + break; + } + } + } + resultState = isExist ? RESULT_OK : RESULT_FAIL; + if(isExist){ +// sb.append("执行“" + exec.getExecCmd() + "”成功;"); +// sb.append("Execute“" + exec.getExecCmd() + "”success;"); + sb.append("i18n_client.AgentCommand.exec_n81i“" + exec.getExecCmd() + "”i18n_client.AgentCommand.success_n81i;"); + }else{ +// sb.append("执行“" + exec.getExecCmd() + "”失败, " + (notExitPids==null ? "PID为空;" : ("PID“"+notExitPids+"”不存在;"))); +// sb.append("Execute" + exec.getExecCmd() + "”failed, " + (notExitPids==null ? "PID is empty;" : ("PID is empty“"+notExitPids+"”do not exist;"))); + sb.append("i18n_client.AgentCommand.exec_n81i" + exec.getExecCmd() + "”failed, " + (notExitPids==null ? "i18n_client.AgentCommand.startCmdFail4_n81i;" : ("PID “"+notExitPids+"”i18n_client.AgentCommand.execFailDesc8_n81i;"))); + } + } else { + resultState = RESULT_FAIL; +// sb.append("Failure to execute“" + exec.getExecCmd() + "”process PID file“" + pidFile.getAbsolutePath() + "”do not exist;"); + sb.append("i18n_client.AgentCommand.exec_n81i“" + exec.getExecCmd() + "”i18n_client.AgentCommand.startCmdFail6_n81i“" + pidFile.getAbsolutePath() + "”i18n_client.AgentCommand.execFailDesc8_n81i;"); + } + } else {// ---非常驻内存,解析结果文件:结果标识(0 成功 1失败)|结果描述 + File resultFile = new File(exec.getExecResult()); + if (resultFile.exists()) { + String[] result = FileWrUtil.cfgFileReader(resultFile); + if (result != null && result.length > 0) { + String[] res = result[0].split("\\|"); + if (res != null && res.length >= 1) { + resultState = Long.parseLong(res[0]); + logger.debug("startCmd resultState-->" + resultState); +// String tt = (resultState == RESULT_OK ? "成功" : "失败"); + String tt = (resultState == RESULT_OK ? "Success" : "Failed"); + if(res.length >= 2){ +// sb.append("Execute“" + exec.getExecCmd() + "”" + tt + "," + res[1] + ";"); + sb.append("i18n_client.AgentCommand.exec_n81i“" + exec.getExecCmd() + "”" + tt + "," + res[1] + ";"); + }else{ +// sb.append("Execute“" + exec.getExecCmd() + "”" + tt + ";"); + sb.append("i18n_client.AgentCommand.exec_n81i“" + exec.getExecCmd() + "”" + tt + ";"); + } + } + } else { + resultState = RESULT_FAIL; +// sb.append("Failure to execute“" + exec.getExecCmd() + "”result file is not written in result file;"); + sb.append("i18n_client.AgentCommand.exec_n81i“" + exec.getExecCmd() + "”i18n_client.AgentCommand.startCmdFail7_n81i;"); + } + } else { + resultState = RESULT_FAIL; +// sb.append("Failure to execute“" + exec.getExecCmd() + "”result file“" + resultFile.getAbsolutePath() + "”does not exist;"); + sb.append("i18n_client.AgentCommand.exec_n81i“" + exec.getExecCmd() + "”i18n_client.AgentCommand.startCmdFail8_n81i“" + resultFile.getAbsolutePath() + "”i18n_client.AgentCommand.execFailDesc8_n81i;"); + } + }// -------------步骤3-1结束 + if(resultMsg!=null && resultMsg.length()>0){ + sb.append(resultMsg + ";"); + } + }else{ + resultState = (stepState == RESULT_START_OK ? RESULT_OK : RESULT_FAIL); + } + + /** + * 步骤4 判断是否回传文件 + */ + if(exec.getReturnFlag()!=null && "Y".equalsIgnoreCase(exec.getReturnFlag().trim())){ + returnFileList.add(exec.getReturnPath()); + } + + if(resultState == RESULT_FAIL){//如果有一个失败,就停止执行 + break; + } + }// for end + + /** + * 步骤5 如果有回传文件,则回传文件并修改结果为中间结果;如果无回传文件,不回传且结果为最终结果 + */ + if(returnFileList.size()>0){ + ReturnFilePO rfPO = new ReturnFilePO(); + rfPO.setTaskId(command.getExecId()); + rfPO.setTaskType(command.getExecType()); + rfPO.setUuid(Contants.AGENT_HOST_UUID); + rfPO.setState(resultState); + //rfPO.setFilePaths(returnFileList); + rfPO.setStartTime(startTime); + rfPO.setEndTime(new Date()); + rfPO.setIsLoop(command.getIsLoop()); + TaskReturnHandle.startTaskReturnFileThread(rfPO, returnFileList); + resultState = (resultState == RESULT_OK) ? RESULT_START_OK : RESULT_START_FAIL; + } + + if(resultState == RESULT_OK || resultState == RESULT_START_OK){ +// resultDesc = "执行成功,详细信息如下:" + sb.toString(); +// resultDesc = "Execution succeeded, details are as follows:" + sb.toString(); + resultDesc = "i18n_client.AgentCommand.startCmdSuccess4_n81i:" + sb.toString(); + }else{ +// resultDesc = "执行失败,详细信息如下:" + sb.toString(); +// resultDesc = "Execution failed with the following details:" + sb.toString(); + resultDesc = "i18n_client.AgentCommand.startCmdFail9_n81i:" + sb.toString(); + } +// logger.debug(resultDesc);//i18nlog + } + + } catch (Exception e) { +// resultDesc = "执行失败:出现异常," + e.getMessage() + ",详细信息请查看日志"; +// resultDesc = "Execution failed: An exception occurred," + e.getMessage() + ",see the logs for details"; + resultDesc = "i18n_client.AgentCommand.startCmdFail10_n81i," + e.getMessage() + ",i18n_client.AgentCommand.execFailDesc10.showDetail_n81i"; + resultState = RESULT_FAIL; + logger.error("Start abnormity: " + Utils.printExceptionStack(e)); + } +// logger.info("启动结果描述信息 >> " + resultDesc);//i18nlog + logger.info("启动结束……"); + + return resultState + RESULT_SEPRATOR + resultDesc; + } + + /** + * 可执行命令,单次执行命令 + * @param execList 命令参数对象集 + * @return + */ + public String singleExecCmd(List execList, Date startTime, long stepState){ + logger.info("单次命令执行开始……"); + String resultDesc = ""; + StringBuffer sb = new StringBuffer(); + long resultState = RESULT_FAIL; + try { + if(execList==null || execList.size()<=0){ +// resultDesc = "执行成功:未指定内容,不需要执行"; + resultDesc = "Execution succeeded: no content specified, no need to execute"; + resultState = RESULT_OK; + logger.debug(resultDesc); + } else { + List returnFileList = new ArrayList(); + for(ParamCmdExec exec : execList){ + if (stepState != RESULT_START_OK + && stepState != RESULT_START_FAIL) {// 若还未执行过,则继续执行,否则,只进行回传文件 + /** + * 步骤1、必要的空判断 + */ + if(exec.getExecCmd()==null || exec.getExecCmd().trim().length()<=0){ +// sb.append("执行“" + exec.getExecCmd() + "”失败,执行命令为空;"); + sb.append("The execution of“" + exec.getExecCmd() + "”failed and the execution command was empty;"); + resultState = RESULT_FAIL; + break; + } + // 判断用户和密码是否正确 + /*boolean flag = ProcessUtil.checkUserPass(exec.getUsername(), exec.getParam1()); + if (!flag) { + sb.append("执行“" + exec.getExecCmd() + "”失败,用户名或密码不正确;"); + resultState = RESULT_FAIL; + break; + }*/ + // 判断用户名是否正确 + if(!ProcessUtil.checkUserOrGroupExist(exec.getUsername(), null)){ +// sb.append("执行“" + exec.getExecCmd() + "”失败,用户名不正确;"); +// sb.append("Failure to execute“" + exec.getExecCmd() + "” with incorrect user name;"); + sb.append("i18n_client.AgentCommand.exec_n81i“" + exec.getExecCmd() + "” i18n_client.AgentCommand.singleCmdFail2_n81i;"); + resultState = RESULT_FAIL; + break; + } + //判断用户是否有执行命令的权限 + //------------待完成su - -c "[ -x jzz_test.py ];echo $?" nmstest; + /** + * 步骤2、执行命令部分 + */ + final String execCmd = exec.getExecCmd(); + final String username = exec.getUsername(); + final String pass = exec.getParam1(); + final String threadName = Thread.currentThread().getName(); + Future future = Common.service.submit(new Callable(){ + @Override + public String call() throws Exception { + thread = Thread.currentThread(); + Thread.currentThread().setName(threadName); + String result = ProcessUtil.runExecGetResult(execCmd, username, pass); + return result; + } + }); + // ----获取最大等待时间(单位秒) + long delay = 3; + if (exec.getMaxWaitTime() != null + && !"".equals(exec.getMaxWaitTime().trim())) { + delay = Long.parseLong(exec.getMaxWaitTime().trim()); + logger.debug("singleExecCmd Timeout time value: " + delay + " seconds"); + } + // ----超过一定时间,终止执行线程,返回结果超时 + try { + String result = future.get(delay, TimeUnit.SECONDS); + logger.debug("singleExecCmd result-->" + result); + // ---解析结果:结果标识(0 成功 1失败)|结果描述 + if (result != null && !result.isEmpty()) { + String[] res = result.split("\\|"); + if (res != null && res.length >= 1) { + resultState = Long.parseLong(res[0]); + logger.debug("singleExecCmd resultState-->" + resultState); +// String tt = (resultState == RESULT_OK ? "成功" : "失败"); +// String tt = (resultState == RESULT_OK ? "Success" : "Failed"); + String tt = (resultState == RESULT_OK ? "i18n_client.AgentCommand.success_n81i" : "i18n_client.AgentCommand.fail_n81i"); + if(res.length >= 2){ +// sb.append("Execute“" + exec.getExecCmd() + "”" + tt + "," + res[1] + ";"); + sb.append("i18n_client.AgentCommand.exec_n81i“" + exec.getExecCmd() + "”" + tt + "," + res[1] + ";"); + }else{ +// sb.append("Execute“" + exec.getExecCmd() + "”" + tt + ";"); + sb.append("i18n_client.AgentCommand.exec_n81i“" + exec.getExecCmd() + "”" + tt + ";"); + } + } + } else { + resultState = RESULT_FAIL; +// sb.append("Execute“" + exec.getExecCmd() + "”failed"); + sb.append("i18n_client.AgentCommand.exec_n81i“" + exec.getExecCmd() + "”i18n_client.AgentCommand.singleCmdFail3_n81i"); + } + } catch (TimeoutException e) { + if(thread!=null && thread.isAlive()){ + thread.stop(); + logger.debug(execCmd + "---singleExecCmd Timeout stop thread--" + thread.isAlive()); + } + future.cancel(true); + resultState = RESULT_FAIL; +// sb.append("执行“" + exec.getExecCmd() + "”失败, 超时;"); +// sb.append("Failed to execute“" + exec.getExecCmd() + "”timeout;"); + sb.append("i18n_client.AgentCommand.exec_n81i“" + exec.getExecCmd() + "”i18n_client.AgentCommand.singleCmdFail4_n81i;"); + logger.debug("---------singleExecCmd timeout----------"); + }catch (InterruptedException e) { + if(thread!=null && thread.isAlive()){ + thread.stop(); + logger.debug(execCmd + "---singleExecCmd Interrupted stop thread--" + thread.isAlive()); + } + future.cancel(true); + resultState = RESULT_FAIL; +// sb.append("Failure to execute“" + exec.getExecCmd() + "”thread was interrupted;"); + sb.append("i18n_client.AgentCommand.exec_n81i“" + exec.getExecCmd() + "”i18n_client.AgentCommand.singleCmdFail5_n81i;"); + logger.debug("---------singleExecCmd Interrupted----------"); + } + }else{ + resultState = (stepState == RESULT_START_OK ? RESULT_OK : RESULT_FAIL); + } + + /** + * 步骤3 判断是否回传文件 + */ + if(exec.getReturnFlag()!=null && "Y".equalsIgnoreCase(exec.getReturnFlag().trim())){ + returnFileList.add(exec.getReturnPath()); + } + + if(resultState == RESULT_FAIL){//如果有一个失败,就停止执行 + break; + } + }// for end + + /** + * 步骤4 如果有回传文件,则回传文件并修改结果为中间结果;如果无回传文件,不回传且结果为最终结果 + */ + if(returnFileList.size()>0){ + ReturnFilePO rfPO = new ReturnFilePO(); + rfPO.setTaskId(command.getExecId()); + rfPO.setTaskType(command.getExecType()); + rfPO.setUuid(Contants.AGENT_HOST_UUID); + rfPO.setState(resultState); + //rfPO.setFilePaths(returnFileList); + rfPO.setStartTime(startTime); + rfPO.setEndTime(new Date()); + rfPO.setIsLoop(command.getIsLoop()); + TaskReturnHandle.startTaskReturnFileThread(rfPO, returnFileList); + resultState = (resultState == RESULT_OK) ? RESULT_START_OK : RESULT_START_FAIL; + } + + if(resultState == RESULT_OK || resultState == RESULT_START_OK){ +// resultDesc = "执行成功,详细信息如下:" + sb.toString(); +// resultDesc = "The execution was successful. The details are as follows:" + sb.toString(); + resultDesc = "i18n_client.AgentCommand.singleCmdSuccess2_n81i:" + sb.toString(); + }else{ +// resultDesc = "执行失败,详细信息如下:" + sb.toString(); +// resultDesc = "Execution failed with the following details:" + sb.toString(); + resultDesc = "i18n_client.AgentCommand.singleCmdFail6_n81i:" + sb.toString(); + } + } + + } catch (Exception e) { +// resultDesc = "执行失败:出现异常," + e.getMessage() + ",详细信息请查看日志"; +// resultDesc = "Execution failed: An exception occurred," + e.getMessage() + ", See the logs for details"; + resultDesc = "i18n_client.AgentCommand.singleCmdFail7_n81i," + e.getMessage() + ",i18n_client.AgentCommand.execFailDesc10.showDetail_n81i"; + resultState = RESULT_FAIL; + logger.error("Single command execution exception: " + Utils.printExceptionStack(e)); + } +// logger.info("单次命令执行结果描述信息 >> " + resultDesc);//i18nlog + logger.info("单次命令执行结束……"); + + return resultState + RESULT_SEPRATOR + resultDesc; + } + + /** + * 取得备份文件的名称:原文件名_version_bak_压缩文件的相应后缀 + * @param oldFileName + * @param version + * @param isAbs + * @return + */ + private String getBakFileName(String oldFileName, long version, boolean isAbs){ + String fileName = ""; + if(oldFileName!=null){ + fileName += oldFileName + "_"; + } + fileName += version + "_bak" + CompressFileMgr.getCompressSuffixByOs(isAbs); + + return fileName; + } + + /** + * 处理相对和绝对文件路径:如果文件本身是绝对路径不做处理;如果文件是相对路径则相对parent下 + * @param filepath 相对或绝对路径的文件 + * @param parent 相对路径文件的父目录 + * @return + * @throws Exception + */ + private String getFilePath(String filepath, String parent) throws Exception{ + if(filepath!=null && filepath.trim().length()>0){ + File file = new File(filepath); + if(file.isAbsolute()){ + return file.getCanonicalPath(); + }else if(parent!=null && parent.trim().length()>0){ + File parentFile = new File(parent); + if(!parentFile.isDirectory()){ + parent = parentFile.getParent(); + } + return new File(parent + File.separator + filepath).getCanonicalPath(); + }else { + return file.getCanonicalPath(); + } + } + return null; + } + + /** + * 删除文件,先对删除的文件做处理:如果是绝对路径直接删除;如果是相对路径则相应处理 + * @param dels 将要删除的文件集 + * @param oppositeDelDir 如果删除文件是相对路径,则为相对路径文件的父目录 + * @return 删除文件的描述信息 + * @throws Exception + */ + private String delete(String[] dels, String oppositeDelDir) throws Exception{ + StringBuffer sb = new StringBuffer(); + if(dels!=null && dels.length>0){ + for(String del : dels){ + if(del==null || del.trim().length()<=0){ + continue; + } + del = getFilePath(del, oppositeDelDir); + if(del==null){ + continue; + } + File file = new File(del); + if(file.exists()){ + FileUtil.delDir(file); +// sb.append("删除”" + file.getCanonicalPath() + "“成功;"); +// sb.append("Delete”" + file.getCanonicalPath() + "“success;"); + sb.append("i18n_client.AgentCommand.deleteSuccess_n81i”" + file.getCanonicalPath() + "“i18n_client.AgentCommand.success_n81i;"); + }else{ +// sb.append("删除”" + file.getCanonicalPath() + "“,文件不存在;"); +// sb.append("Delete”" + file.getCanonicalPath() + "“,the file does not exist;"); + sb.append("i18n_client.AgentCommand.deleteFail_n81i”" + file.getCanonicalPath() + "“,i18n_client.AgentCommand.deleteFail.noFile_n81i;"); + } + } + } + if(sb.length()>0){ + sb.deleteCharAt(sb.length()-1); + } + return sb.toString(); + } + + /** + * 对是否字段(Y\N)的默认值处理 + * @param field + * @return + */ + private String handleYesOrNoField(String field){ + if(field==null || field.trim().length()<=0){ + return "N"; + }else if("Y".equalsIgnoreCase(field.trim())){ + return "Y"; + }else{ + return "N"; + } + } + + /** + * 升级中的覆盖更新参数处理: + * *逆向任务,按恢复到的版本和本地备份目录来处理覆盖源文件;恢复目录,如果是相对则相对升级的覆盖目录,如果是绝对则不变 + * *升级任务,按升级文件的路径处理源文件 + * @param cfuList 升级参数列表 + * @param reVersion 恢复到的版本 + * @param upgradePath 升级文件的路径 + * @return 覆盖更新数组集 + * @throws Exception + */ + private ParamCoverUpdate[] handleCoverUpdates(List cfuList, + Long reVersion, String upgradePath) throws Exception { + List pcuList = new ArrayList(); + for (ParamUpgrade cfu : cfuList) { + if (reVersion != null && reVersion.longValue() > 0) {//逆向任务,恢复 + for (ParamCoverUpdate update : cfu.getRecoverys()) { + //必须先处理恢复目录 + update.setCover(getFilePath(update.getCover(), cfu.getCover())); + //再处理恢复源文件 + update.setSource(getRecoverSource(update, reVersion)); + pcuList.add(update); + } + } else {//升级任务 + ParamCoverUpdate update = new ParamCoverUpdate(); + update = new ParamCoverUpdate(); + update.setSource(getFilePath(cfu.getFileName(), upgradePath)); + update.setCover(cfu.getCover()); + update.setIsCreateCover(cfu.getIsCreateCover()); + update.setIsAbs(cfu.getIsAbs()); + update.setDelete(cfu.getDelete()); + + pcuList.add(update); + } + } + ParamCoverUpdate[] updates = new ParamCoverUpdate[cfuList.size()]; + return pcuList.toArray(updates); + } + + /** + * 升级中的恢复参数的源处理:source应为 localBackupPath + source + bakFileName(coverFileName_version_bak_压缩后缀) + * @param update 覆盖更新对象 + * @param reVersion 恢复到的版本 + * @return 恢复参数的源文件 + * @throws Exception + */ + private String getRecoverSource(ParamCoverUpdate update, Long reVersion) + throws Exception { + // 逆向任务,source是原任务的备份目标目录(相对的),cover是原任务的备份过的文件 + // source还可以是操作人员自己备份的文件(完整的绝对路径且必须存在),如果source文件不存在,则按上面默认的方法重新拼写 + String source = update.getSource(); + logger.debug("getRecoverSource source----" + update.getSource()); + logger.debug("getRecoverSource cover----" + update.getCover()); + if (update.getSource() != null + && !new File(update.getSource()).exists()) { + String oldFileName = ""; + if (update.getCover() != null) { + oldFileName = new File(update.getCover()).getCanonicalFile().getName(); + } + boolean isAbs = false; + if ("Y".equals(handleYesOrNoField(update.getIsAbs()))) { + isAbs = true; + } + source = Contants.localBackupPath + File.separator + + update.getSource() + File.separator + + getBakFileName(oldFileName, reVersion, isAbs); + } + return source; + } + + private void backup(File srcFile, File destDir, String[] excepts) throws Exception{ + if (!srcFile.exists()) { + return; + } + if (!srcFile.isDirectory()) { + boolean flag = true; + if (excepts != null && excepts.length > 0) { + for (String except : excepts) { + if (srcFile.getCanonicalPath().equalsIgnoreCase(except)) { + flag = false; + break; + } + } + } + if (flag) { + FileUtils.copyFileToDirectory(srcFile, destDir); + } + } else if (srcFile.isDirectory()) { + destDir = new File(destDir.getAbsolutePath() + File.separator + + srcFile.getName()); + for (File f : srcFile.listFiles()) { + boolean flag = true; + if (excepts != null && excepts.length > 0) { + for (String except : excepts) { + if (f.getCanonicalPath().equalsIgnoreCase(except)) { + flag = false; + break; + } + } + } + if (flag) { + if (!f.isDirectory()) { + FileUtils.copyFileToDirectory(f, destDir); + } else if (f.isDirectory()) { + backup(f, new File(destDir.getAbsolutePath()), excepts); + } + } + } + } + } + +} diff --git a/src/com/nis/nmsclient/thread/task/LoopTaskThread.java b/src/com/nis/nmsclient/thread/task/LoopTaskThread.java new file mode 100644 index 0000000..b3e8a36 --- /dev/null +++ b/src/com/nis/nmsclient/thread/task/LoopTaskThread.java @@ -0,0 +1,106 @@ +package com.nis.nmsclient.thread.task; + +import java.util.Date; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.apache.log4j.Logger; + +import com.nis.nmsclient.common.Common; +import com.nis.nmsclient.model.CommandPO; +import com.nis.nmsclient.util.Utils; + +public class LoopTaskThread extends Thread{ + Logger logger = Logger.getLogger(LoopTaskThread.class); + + private String threadName; + private long loopDelay; + private CommandPO command; + + private long i = 0; + private Future future = null; + private Thread thread; + + private boolean isCancle; + + public LoopTaskThread(String threadName, CommandPO command, long loopDelay, Future singleFuture, Thread singleThread){ + this.threadName = threadName; + this.loopDelay = loopDelay; + this.command = command; + this.future = singleFuture; + this.thread = singleThread; + + isCancle = false; + } + + public synchronized void cancle() { + isCancle = true; + } + + public void run() { + i++; +// Thread.currentThread().setName(threadName + " 周期" + i); + Thread.currentThread().setName(threadName + " Cycle" + i); + long et = System.currentTimeMillis();// 本次开始时间,即上次执行结束时间 + long st = et - (i * loopDelay * 60 * 1000);// 上次开始时间 + try { + if (i == 1 && future != null + && !future.isCancelled() + && !future.isDone()) { + try { + future.get(1, TimeUnit.MICROSECONDS); + } catch (TimeoutException e) { + if(thread!=null && thread.isAlive()){ + thread.stop(); + logger.debug("LoopTaskThread run Timeout stop singleThread--" + thread.isAlive()); + } + future.cancel(true); + } + + } + if(!isCancle){ + // 周期开始执行 + future = Common.scheduled.schedule(new Runnable() { + public void run() { + thread = Thread.currentThread(); +// Thread.currentThread().setName(threadName + " 周期" + i); + Thread.currentThread().setName(threadName + " Cycle" + i); + new AgentCommand(command).exec(); + } + }, 0, TimeUnit.MILLISECONDS); + try { + future.get(loopDelay, TimeUnit.MINUTES); + } catch (TimeoutException e) { + if(thread!=null && thread.isAlive()){ + thread.stop(); + logger.debug("LoopTaskThread run Timeout stop thread--" + thread.isAlive()); + } + future.cancel(true); + logger.debug("---------LoopTaskThread run timeout----------"); + TaskResultOper.sendTaskResult(command.getExecId(), + command.getExecType(), + AgentCommand.RESULT_FAIL, +// "本周期任务执行超时", "", new Date(st), +// "this task execution timeout", "", new Date(st), + "i18n_client.LoopTaskThread.loopTaskOuttime_n81i", "", new Date(st), + new Date(et), false, command.getIsLoop()); + }catch (InterruptedException e) { + if(thread!=null && thread.isAlive()){ + thread.stop(); + logger.debug("LoopTaskThread run Interrupted stop thread--" + thread.isAlive()); + } + future.cancel(true); + logger.debug("---------LoopTaskThread run Interrupted----------"); + } + } + + if(thread!=null){ + logger.debug("LoopTaskThread run thread state--" + thread.isAlive()); + } + } catch (Exception e) { + logger.info(Utils.printExceptionStack(e)); + } + } +} + diff --git a/src/com/nis/nmsclient/thread/task/TaskReqHandle.java b/src/com/nis/nmsclient/thread/task/TaskReqHandle.java new file mode 100644 index 0000000..3381742 --- /dev/null +++ b/src/com/nis/nmsclient/thread/task/TaskReqHandle.java @@ -0,0 +1,397 @@ +package com.nis.nmsclient.thread.task; + +import java.io.File; +import java.io.IOException; +import java.util.Date; +import java.util.concurrent.Callable; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import net.sf.json.JSONObject; + +import org.apache.commons.io.FileUtils; +import org.apache.log4j.Logger; + +import com.nis.nmsclient.common.Common; +import com.nis.nmsclient.common.Contants; +import com.nis.nmsclient.model.CommandPO; +import com.nis.nmsclient.model.ParamFilePush; +import com.nis.nmsclient.model.ParamUpgrade; +import com.nis.nmsclient.model.Task4; +import com.nis.nmsclient.model.Task6; +import com.nis.nmsclient.thread.socket.CommonSocket; +import com.nis.nmsclient.util.FileUtil; +import com.nis.nmsclient.util.ProcessUtil; +import com.nis.nmsclient.util.Utils; + +public class TaskReqHandle { + Logger logger = Logger.getLogger(TaskReqHandle.class); + private Thread singleThread; + + /** + * 任务请求处理步骤1:分析任务请求参数,分不同任务类型处理 + */ + public void taskHandle(String str){ + Date execTime = new Date(); + boolean flag = true; + int taskType = 0; + long taskId = 0; + String threadName = null; + CommandPO command = null; + try { + JSONObject jsonObj = JSONObject.fromObject(str); + if(str.contains("typeInfo")){ + taskType = jsonObj.getInt("typeInfo"); + } + if(str.contains("taskInfo")){ + JSONObject jsonObj2 = jsonObj.getJSONObject("taskInfo"); + Object obj = null; + /** + * 任务类型:2 非流文本数据获取,3 流文本数据获取,4 命令执行,5 shell注册, 6升级 + */ + switch (taskType) { + case 4: + obj = JSONObject.toBean(jsonObj2,Task4.class); + Task4 task4 = (Task4) obj; + taskId = task4.getTaskId(); + /** + * 命令类型:1 Agent原生支持命令,2可执行命令(2 脚本,3 shell命令) + */ + if(task4.getCommandType() == 1){ +// threadName = "原生命令 id:" + task4.getTaskId() + ">>" + task4.getCommandName(); + threadName = "Native command ID:" + task4.getTaskId() + ">>" + task4.getCommandName(); + }else if(task4.getCommandType() == 2){ +// threadName = "可执行命令 id:" + task4.getTaskId(); + threadName = "Executable command ID:" + task4.getTaskId(); + } + command = new CommandPO(); + command.setExecId(task4.getTaskId()); + command.setExecType(task4.getTaskType()); + command.setCommandName(task4.getCommandName()); + command.setCommandParam(task4.getCommandParam()); + command.setExecState(task4.getState()); + command.setExecVersion(null); + command.setIsLoop(task4.getIsLoop()); + + handleTaskThread(task4.getTaskId(), task4.getStartTime(), task4.getEndTime(), task4 + .getIsLoop(), task4.getLoopDelay(), command, threadName, task4.getMissionState()); + + break; + case 6: + obj = JSONObject.toBean(jsonObj2,Task6.class); + Task6 task6 = (Task6) obj; + taskId = task6.getTaskId(); +// threadName = "升级 id:" + task6.getTaskId() + ">>" + task6.getCommandName(); + threadName = "Upgrade ID:" + task6.getTaskId() + ">>" + task6.getCommandName(); + command = new CommandPO(); + command.setExecId(task6.getTaskId()); + command.setExecType(task6.getTaskType()); + command.setCommandName(task6.getCommandName()); + command.setCommandParam(task6.getCommandParam()); + command.setExecState(task6.getState()); + command.setExecVersion(task6.getVersion()); + command.setSrcPath(getUpgradeTaskPushPath(task6.getTaskId())); + + handleTaskThread(task6.getTaskId(), task6.getUpgradeTime(), null, 0, 0, command, threadName, 0); + break; + default: + flag = false; + break; + } + }else{ + flag = false; + } + } catch (Exception e) { + logger.error(Utils.printExceptionStack(e)); + flag = false; + } + + if(!flag){ + TaskResultOper.sendTaskResult(taskId, taskType, +// AgentCommand.RESULT_FAIL, "发送内容格式不正确", "", execTime, new Date(), false, -1l); +// AgentCommand.RESULT_FAIL, "Incorrect content format", "", execTime, new Date(), false, -1l); + AgentCommand.RESULT_FAIL, "i18n_client.TaskReqHandle.sendInfoFormatErr_n81i", "", execTime, new Date(), false, -1l); + } + } + + /** + * 文件推送处理 + */ + public String filePush(CommonSocket socket, String taskParam, long taskId, boolean isUpgrade){ + String msg = null; + StringBuffer sb = new StringBuffer(); + File tempDir = null; + try { + tempDir = new File(Contants.localTempPath + File.separator + + "filepush_" + taskId); + if (!tempDir.exists()) { + tempDir.mkdirs(); + } + // ------步骤1:接收Md5校验的推送文件到临时目录 + int flag = socket.bpReceiveFileByBathMd5(tempDir.getAbsolutePath()); + + if (flag == 0){// ------步骤2:接收成功,与参数比对 + if(taskParam==null || "".equals(taskParam)){ + msg = Contants.COMMON_MSG_FAIL + Contants.COMMON_MSG_SEPRATOR + "i18n_client.TaskReqHandle.pushFileParamIsNull_n81i"; +// logger.info(msg);//i18nlog + return msg; + } + // ------步骤2-1:解析参数 + String[] params = taskParam.trim().split(AgentCommand.PARAM_SEPRATOR); + if (params != null && params.length >= 1) { + for (int i = 0; i < params.length; i++) { + //2012-4-28 任务参数中对路径的格式化将在界面上进行,原因此处会对转义字符的\也转换为/,故replace("\\", "/")去掉 + params[i] = params[i].trim().replaceAll("[\n\t\r]","");//.replace("\\", "/");//[\\s*\n\t\r] + logger.debug("filePush-->param: " + params[i]); + ParamFilePush fParam = null; + if(isUpgrade){ + ParamUpgrade cfu = (ParamUpgrade) JSONObject.toBean(JSONObject + .fromObject(params[i]), ParamUpgrade.class); + fParam = new ParamFilePush(); + fParam.setFileName(cfu.getFileName()); + fParam.setUsername(cfu.getUsername()); + fParam.setGroupName(cfu.getGroupName()); + fParam.setParam1(cfu.getParam1()); + }else{ + fParam = (ParamFilePush) JSONObject.toBean( + JSONObject.fromObject(params[i]), + ParamFilePush.class); + } + if(fParam.getDestPath()==null || fParam.getDestPath().trim().length()<=0){ + fParam.setDestPath(getUpgradeTaskPushPath(taskId));//设置默认推送目的地 + logger.debug("filePush-->destPath: " + fParam.getDestPath()); + } + if(fParam.getFileName()==null || fParam.getFileName().trim().length()<=0){ +// msg = "推送文件名参数为空"; +// msg = "File push parameters are empty"; + msg = "i18n_client.TaskReqHandle.pushFileNameParamIsNull_n81i"; +// logger.debug(msg);//i18nlog + break; + } + /*if(!ProcessUtil.checkUserPass(fParam.getUsername(), fParam.getParam1())){ + msg = "[" + fParam.getFileName() + "]推送文件的用户名或密码不正确;"; + logger.debug(msg); + break; + }*/ + // 判断用户名是否正确 + if(!ProcessUtil.checkUserOrGroupExist(fParam.getUsername(), fParam.getGroupName())){ +// msg = "[" + fParam.getFileName() + "]推送文件的属主或属群不正确;"; +// msg = "[" + fParam.getFileName() + "]The owner or group of the push file is incorrect;"; + msg = "[" + fParam.getFileName() + "]i18n_client.TaskReqHandle.userGroupErr_n81i;"; +// logger.debug(msg);//i18nlog + break; + } + // ------步骤2-2:文件存在并与Md5值比较文件是否完整 + File pushFile = new File(tempDir.getAbsolutePath() + + File.separator + fParam.getFileName()); + if (!pushFile.exists()){ +// msg = "推送临时文件不存在,请检查推送文件名称与参数文件名(" +// + fParam.getFileName() + ")是否一致"; +// msg = "The push temporary file does not exist. Please check whether the push file name is consistent with the parameter file name(" +// + fParam.getFileName() + ")"; + msg = "i18n_client.TaskReqHandle.pushFileNotExists_n81i(" + + fParam.getFileName() + ")"; +// logger.warn(msg + "--" + pushFile.getAbsolutePath());//i18nlog + break; + } + // ------步骤2-3:判断推送目录是否存在,不存在创建 + File destFile = new File(fParam.getDestPath() + + File.separator + fParam.getFileName()); + if(!destFile.getParentFile().exists()){ + destFile.getParentFile().mkdirs(); + } + // ------步骤2-4:判断是否直接覆盖 + if (fParam.getIsCover() != null + && "Y".equalsIgnoreCase(fParam.getIsCover())) {// 覆盖,则直接Copy并赋权限与所有者 + if (destFile.exists()) { + //destFile.delete_bak(); + //使用删除文件公共方法 + FileUtil.delDir(destFile); + logger.debug("filePush delete file--" + destFile.getAbsolutePath()); + //FileUtil.checkParentDirExist(destFile); + } + msg = copyAndSetPermission(pushFile + .getCanonicalPath(), destFile + .getCanonicalPath(), fParam.getUsername(), + fParam.getGroupName(), fParam + .getPermisson()); + } else if (!destFile.exists()) {// 不覆盖,则判断文件不存在的话,再Copy并赋权限与所有者 + msg = copyAndSetPermission(pushFile + .getCanonicalPath(), destFile + .getCanonicalPath(), fParam.getUsername(), + fParam.getGroupName(), fParam + .getPermisson()); + } + if(msg==null || msg.length()<=0){ +// sb.append("[" + fParam.getFileName() + "]成功推送到[" + fParam.getDestPath() + "];"); +// sb.append("[" + fParam.getFileName() + "]successfully pushed to[" + fParam.getDestPath() + "];"); + sb.append("[" + fParam.getFileName() + "]i18n_client.TaskReqHandle.successPush_n81i[" + fParam.getDestPath() + "];"); + logger.debug("推送文件" + (i+1) + "成功---" + pushFile.getCanonicalPath()); + }else{ +// msg = msg+"[" + fParam.getFileName() + "]推送失败;";//文件推送失败的具体原因 + msg = msg+"[" + fParam.getFileName() + "]i18n_client.TaskReqHandle.pushFail_n81i;";//文件推送失败的具体原因 + logger.debug("推送文件" + (i+1) + "失败---" + pushFile.getCanonicalPath()); + break; + } + }//for end + } else { +// msg = "文件推送参数不正确"; +// msg = "File push parameter is incorrect"; + msg = "i18n_client.TaskReqHandle.pushParamErr_n81i"; +// logger.warn(msg + "<" + taskParam + ">");//i18nlog + } + //所有文件推送成功,删除临时接收文件目录 + if(msg==null || msg.length()<=0){ + if(tempDir!=null && tempDir.exists()){ + try { + logger.debug("删除临时目录--" + tempDir.getAbsolutePath()); + FileUtils.deleteDirectory(tempDir); + FileUtil.checkParentDirExist(tempDir); + } catch (IOException e) { + } + } + } + }else { + socket.close(); + } + + if(msg == null){ + msg = Contants.COMMON_MSG_SUCCESS + Contants.COMMON_MSG_SEPRATOR + sb.toString(); + }else { + sb.append(msg); + msg = Contants.COMMON_MSG_FAIL + Contants.COMMON_MSG_SEPRATOR + sb.toString(); + } + + } catch (Exception e) { + logger.error("Receive push file exception:" + Utils.printExceptionStack(e)); +// msg = Contants.COMMON_MSG_FAIL + Contants.COMMON_MSG_SEPRATOR + "接收推送文件异常," + e.getMessage(); +// msg = Contants.COMMON_MSG_FAIL + Contants.COMMON_MSG_SEPRATOR + "Received push file exception," + e.getMessage(); + msg = Contants.COMMON_MSG_FAIL + Contants.COMMON_MSG_SEPRATOR + "i18n_client.TaskReqHandle.reciveFileErr_n81i," + e.getMessage(); + return msg; + }finally{ + if(tempDir!=null && tempDir.exists() && tempDir.listFiles().length==0){ + try { + FileUtils.deleteDirectory(tempDir); + logger.debug("finally删除临时目录--" + tempDir.getAbsolutePath()); + FileUtil.checkParentDirExist(tempDir); + } catch (IOException e) { + } + } + } + + return msg; + } + + /** + * 文件推送部分的拷备工作,由临时文件目录拷备到推送的最终目的地,并赋相应的权限组 + */ + private String copyAndSetPermission(String source, String destFile, String user, String group, String permission) throws Exception{ + String result = null; + if (source != null && destFile != null) { + // 根据操作系统确定获取进程ID的方式 + String os = System.getProperty("os.name"); + if (os.startsWith("Windows")) { + FileUtils.copyFile(new File(source), new File( + destFile));//目标路径不存在自动创建 + } else if (os.startsWith("Linux")) { + StringBuffer sb = new StringBuffer(); + //source destFile都不能含有空格 + source = source.replace(" ", "\\ "); + destFile = destFile.replace(" ", "\\ "); + sb.append("\\cp -f " + source + " " + destFile + ";");//2015-11-6 hyx: cp - f修改成\\cp -f (有时候如果不加\\会提示是否,就会有问题) + if (permission != null && !"".equals(permission.trim())) { + sb.append("chmod " + permission + " " + + destFile + ";"); + } + if (user != null && !"".equals(user.trim())) { + sb.append("chown " + user + " " + destFile + ";"); + } + if (group != null && !"".equals(group.trim())) { + sb.append("chgrp " + group + " " + destFile); + } + result = ProcessUtil.execLinuxCmd(sb.toString()); + } else { + throw new IOException("unknown operating system: " + os); + } + }else{ +// result = "源文件或目标文件为空"; +// result = "The source file or target file is empty"; + result = "i18n_client.TaskReqHandle.sourceOrTargetIsNull_n81i"; + } + + return result; + } + + + /** + * 任务请求处理步骤2:将分析包装好的任务,统一判断处理并添加到线程中执行 + */ + public void handleTaskThread(Long taskId, Long startTime, Long endTime, + long isLoop, long loopDelay, final CommandPO command, + final String threadName, long missionState) { + if(missionState == AgentCommand.MISSION_CANCEL_START){//如果任务状态为,撤消任务 + logger.warn("The task is in the revocation, and the ID is not processed:" + taskId); + return; + } + if(Common.getTaskFuture(taskId)!=null){//当前任务已存在执行,则不执行该当前任务 + logger.warn("The task already exists to execute the ID:" + taskId); + return; + } + // 设置任务结束时间,且当前时间已超过任务结束时间 + if (endTime != null && endTime.longValue() > 0 + && endTime.longValue() <= System.currentTimeMillis()) { + logger.warn("The task has expired ID:" + taskId); + return; + } + long delay = 0; + if (startTime != null) { + delay = startTime - System.currentTimeMillis(); + } + ScheduledFuture taskFuture = null; + LoopTaskThread loopTaskThread = null; + if (isLoop == 0) {// 非周期任务 + taskFuture = Common.scheduled.schedule(new Runnable() { + public void run() { + Thread.currentThread().setName(threadName); + new AgentCommand(command).exec(); + } + }, delay, TimeUnit.MILLISECONDS); + } else { + Future singleFuture = null; + if(delay <= 0){//开始时间之后接到任务,先执行一次,第二次按周期点执行 + long now = System.currentTimeMillis(); + long cnt = (now - startTime)/(loopDelay * 60 * 1000); + if((now - startTime)%(loopDelay * 60 * 1000)!=0){ + delay = startTime + loopDelay *60 *1000 * (cnt + 1) - System.currentTimeMillis(); + ///仅执行一次的,并在周期执行代码中第一次执行判断单次执行完成与否,未完成结束掉 + singleFuture = Common.scheduled.schedule(new Runnable() { + public void run() { + singleThread = Thread.currentThread(); +// Thread.currentThread().setName(threadName + " 周期单次"); + Thread.currentThread().setName(threadName + " Periodic Single Time"); + new AgentCommand(command).exec(); + } + }, 0, TimeUnit.MILLISECONDS); + } + } + loopTaskThread = new LoopTaskThread(threadName, command, loopDelay, singleFuture, singleThread); + taskFuture = Common.scheduled.scheduleAtFixedRate(loopTaskThread, delay, loopDelay * 60 * 1000, TimeUnit.MILLISECONDS); + // 周期任务,若设置结束时间,则添加取消线程 + if (endTime != null && endTime.longValue() > 0) { + long endDelay = endTime.longValue() - System.currentTimeMillis(); + if (endDelay > 0) { + Common.cancleTaskFuture(taskId, endDelay); + } + }// 取消线程结束 + + } + // 将正在执行的任务添加到全局变量,目的是避免重复执行任务 + Common.putTaskFuture(taskId, taskFuture, loopTaskThread); + } + + public static String getUpgradeTaskPushPath(long taskId){ + return Contants.localUploadsPath + File.separator + taskId; + } +} + \ No newline at end of file diff --git a/src/com/nis/nmsclient/thread/task/TaskResultOper.java b/src/com/nis/nmsclient/thread/task/TaskResultOper.java new file mode 100644 index 0000000..ee4130f --- /dev/null +++ b/src/com/nis/nmsclient/thread/task/TaskResultOper.java @@ -0,0 +1,327 @@ +package com.nis.nmsclient.thread.task; + +import java.io.File; +import java.util.Date; +import java.util.concurrent.Future; + +import org.apache.log4j.Logger; + +import com.nis.nmsclient.common.Common; +import com.nis.nmsclient.common.Contants; +import com.nis.nmsclient.common.VersionCfg; +import com.nis.nmsclient.config.DetecConfOper; +import com.nis.nmsclient.thread.socket.CommonSocket; +import com.nis.nmsclient.thread.socket.SSLClient; +import com.nis.nmsclient.thread.socket.ServerCollectData; +import com.nis.nmsclient.util.FileUtil; +import com.nis.nmsclient.util.FileWrUtil; +import com.nis.nmsclient.util.Utils; +import com.nis.nmsclient.util.ZipUtil; + +public class TaskResultOper { + static Logger logger = Logger.getLogger(DetecConfOper.class); + + /** + * Agent在启动时,发送所有之前发送失败的任务结果 + */ + public static void initSendAllTaskResult(){ + try { + //针对结果文件过多时打包上传未完成的文件继续上传 + File taskDir = new File(Contants.localTaskPath); + if (!taskDir.exists()) { + return; + } + File[] zipArr = FileUtil.getFilesEndWith(taskDir, ".zip"); + if (zipArr != null && zipArr.length > 0) { + for (File file : zipArr) { + if (!file.getName().startsWith(CommonSocket.BP_TYPE_TASK_RESULT)) { + continue; + } + Future future = Common.service.submit(new SSLClient(Thread + .currentThread().getName(), + CommonSocket.REQ_BP_UPLOAD_FIFE, new String[] { + CommonSocket.BP_TYPE_TASK_RESULT, file.getAbsolutePath() })); + future.get(); + } + } + //------------------------------------- + + File resultDir = new File(getTaskResultPath()); + if(!resultDir.exists()){ + return; + } + File[] fileArr = FileUtil.getFilesEndWith(resultDir, Contants.TASK_RESULT_FILE_SUFFIX); + if(fileArr == null || fileArr.length == 0){ + /* + * 当任务正常执行完成或者取消后则从全局变量移除 + */ + Common.removeCancelAndDoneTaskFuture(); + return; + } + //--- 将所有任务结果文件一起打包,发送 + if(fileArr.length > Contants.COMMON_ZIP_MIN_SIZE){ + //与Server通信 + Future serFuture = Common.service.submit(new SSLClient( + Thread.currentThread().getName(), + CommonSocket.REQ_HAND_SHAKE, null)); + if (!Contants.isSucessByResult((String) serFuture.get())) { + return; + } + + int zipCnt = fileArr.length/Contants.COMMON_ZIP_MAX_SIZE; + if(zipCnt>0){//2013-5-6 未上传的结果文件太多时,将结果文件压缩为多个文件 + for(int i=0; i future = Common.service.submit(new SSLClient(Thread.currentThread() + .getName(), CommonSocket.REQ_BP_UPLOAD_FIFE, + new String[] { CommonSocket.BP_TYPE_TASK_RESULT, compressFileStr })); + future.get(); + } + }else{ + // 压缩并发送任务结果 + String compressFileStr = Contants.localTaskPath + + File.separator + + CommonSocket.addTimeTagForFileName(CommonSocket.BP_TYPE_TASK_RESULT, null, true) + + ".zip"; + // 2013-03-22 由于DC再次获取未保存任务结果这个功能的实现,现修改将任务结果和回传文件压缩时不删除文件,而是将其移动到相应的日期目录 + ZipUtil.zipWithMoveFile(resultDir.listFiles(), compressFileStr, true); + //发送 + Future future = Common.service.submit(new SSLClient(Thread.currentThread() + .getName(), CommonSocket.REQ_BP_UPLOAD_FIFE, + new String[] { CommonSocket.BP_TYPE_TASK_RESULT, compressFileStr })); + future.get(); + } + }else{//-- 按正常的一个结果一个结果的发送 + fileArr = FileUtil.sortASCByFileName(fileArr); //按文件名升序排列,任务结果文件名都有时间后缀(ms) + StringBuffer sb = new StringBuffer(); + for(File file : fileArr){ + sb.delete(0, sb.length()); + if(!file.exists() || !file.isFile()){ + continue; + } + String[] resultArr = FileWrUtil.cfgFileReader(file); + if(resultArr!=null && resultArr.length>0){ + for(String res : resultArr){ + sb.append(res + ";"); + } + sb.deleteCharAt(sb.length()-1); + Future future = Common.service.submit(new SSLClient( +// "上传任务结果", + "Upload Task Results", + CommonSocket.REQ_TASK_RESULT, sb.toString())); + String msg = (String) future.get(); + if (Contants.isSucessByResult(msg)) { + // 移动上传成功的任务结果到指定日期目录 + ServerCollectData.moveTaskResultToDateDir(file); + } + }else{ + // 移动上传成功的任务结果到指定日期目录 + ServerCollectData.moveTaskResultToDateDir(file); + } + } + } + } catch (Exception e) { + logger.error("Upload task result exception:" + Utils.printExceptionStack(e)); + } + } + + /** + * 处理Agent自动升级的最终结果文件,即升级后是否启动成功 + * Agent升级的临时结果文件,初始写入状态为升级失败: + * 1、当启动失败后将其临时文件后缀改为任务结果文件的后缀; + * 2、当启动成功后先修改文件第一行的后两项内容为执行状态与描述为成功,再改其后缀。 + * + * @param isSuccess + */ + public static void handerAgentUpgradeResult(boolean isSuccess){ + try { + File dir = new File(getTaskResultPath()); + if(!dir.exists()){ + return; + } + File[] fileArr = FileUtil.getFilesEndWith(dir, Contants.TASK_RESULT_AGENTTMPFILE_SUFFIX); + fileArr = FileUtil.sortASCByFileName(fileArr); //按文件名升序排列,任务结果文件名都有时间后缀(ms) + if (fileArr != null && fileArr.length > 0) { + for(int i=0; i 0) { + int descIndex = msgs[0] + .lastIndexOf(Contants.COMMON_MSG_SEPRATOR); + int stateIndex = msgs[0].substring(0, descIndex) + .lastIndexOf(Contants.COMMON_MSG_SEPRATOR); + msgs[0] = msgs[0].substring(0, stateIndex) + + Contants.COMMON_MSG_SEPRATOR + AgentCommand.RESULT_OK +// + Contants.COMMON_MSG_SEPRATOR + "重启成功"; + + Contants.COMMON_MSG_SEPRATOR + "i18n_client.TaskResultOper.restart_n81i"; + + FileWrUtil.cfgFilePrinter(fileArr[i], Contants.charset, msgs); + + int taskIdIndex = msgs[0].indexOf(Contants.COMMON_MSG_SEPRATOR); + //处理写入当前更新的版本信息 + String taskId = msgs[0].substring(0, taskIdIndex); + Long curVer = Long.parseLong(VersionCfg + .getValue(VersionCfg.NAGENT_VERSION)); + if (curVer < Long.parseLong(taskId.trim())) { + VersionCfg.setValue(VersionCfg.NAGENT_VERSION, taskId); + logger.info("NC更新为版本" + taskId); + } + } + } catch (Exception e) { + logger.error("Handling the exception of the NC upgrade result file:" + Utils.printExceptionStack(e)); + } + } + String fileStr = fileArr[i].getAbsolutePath(); + int index = fileStr.lastIndexOf(Contants.TASK_RESULT_AGENTTMPFILE_SUFFIX); + fileStr = fileStr.substring(0, index); + fileArr[i].renameTo(new File(fileStr + Contants.TASK_RESULT_FILE_SUFFIX)); + } + } + } catch (Exception e) { + logger.error("Handling the exception of the NC upgrade result file:" + Utils.printExceptionStack(e)); + } + } + + /** + * 发送任务执行结果:若发送失败写入文件 + */ + /*private static void sendTaskResult(long taskId, long taskType, String msg) { + try{ + Future future = Common.service.submit(new SSLClient( + Thread.currentThread().getName(), + CommonSocket.REQ_TASK_RESULT, msg)); + + String result = (String) future.get(); + + if (!Contants.isSucessByResult(result)) {//失败 + File file = new File(getTaskResultFile(taskType, taskId)); + if(!file.getParentFile().exists()){ + file.getParentFile().mkdirs(); + } + FileWrUtil.cfgFilePrinter(file, Contants.charset, new String[]{msg}); + } + }catch (Exception e) { + logger.error("发送任务结果异常:" + Utils.printExceptionStack(e)); + } + }*/ + + /** + * 发送任务执行结果:判断是否是Server升级,若是直接写入文件,若不是则发送结果 + * @param taskId 任务ID + * @param taskType 任务类型 + * @param resultState 执行结果状态 + * @param resultDesc 执行结果描述 + * @param resultConfig + * @param startTime 开始执行时间 + * @param endTime 执行结束时间 + * @param isServer 是否是Server升级 + * @param isLoop 是否是循环任务 + */ + /*public static void sendTaskResult(long taskId, long taskType, + long resultState, String resultDesc, String resultConfig, + Date startTime, Date endTime, boolean isServer, long isLoop) { + try { + String msg = getTaskResultMsg(taskId, taskType, resultState, + resultDesc, resultConfig, startTime, endTime, isLoop); + if(isServer){//如果是Server升级,直接写入文件 + File file = new File(getTaskResultFile(taskType, taskId)); + if(!file.getParentFile().exists()){ + file.getParentFile().mkdirs(); + } + FileWrUtil.cfgFilePrinter(file, Contants.charset, new String[]{msg}); + }else{//反之,发送任务结果 + sendTaskResult(taskId, taskType, msg); + } + } catch (Exception e) { + logger.error("发送任务结果异常:" + Utils.printExceptionStack(e)); + } + }*/ + + /** + * 发送任务结果: 将结果保存到文件,等待DC主动来收集 + * @date Jan 15, 2013 + * @author zhenzhen + * @version + */ + public static void sendTaskResult(long taskId, long taskType, + long resultState, String resultDesc, String resultConfig, + Date startTime, Date endTime, boolean isServer, long isLoop) { + try { + // 2013-4-9 为了防止多步操作时结果文件名重复,所以暂停50ms为了使时间后缀不一样 + if (resultState > AgentCommand.RESULT_SEND_OK) { + try {Thread.sleep(50);} catch (Exception ignored) { } + } + + String msg = getTaskResultMsg(taskId, taskType, resultState, + resultDesc, resultConfig, startTime, endTime, isLoop); + File file = new File(getTaskResultFile(taskType, taskId)); + if(!file.getParentFile().exists()){ + file.getParentFile().mkdirs(); + } + FileWrUtil.cfgFilePrinter(file, Contants.charset, new String[]{msg}); + } catch (Exception e) { + logger.error("Send task result exception:" + Utils.printExceptionStack(e)); + } + } + + /** + * 按指定的分隔符和顺序拼写任务执行结果信息 + */ + public static String getTaskResultMsg(long taskId, long taskType, + Long resultState, String resultDesc, String resultConfig, + Date startTime, Date endTime, long isLoop) { + StringBuffer sb = new StringBuffer(); + sb.append(taskId); + sb.append(Contants.COMMON_MSG_SEPRATOR); + sb.append(taskType); + sb.append(Contants.COMMON_MSG_SEPRATOR); + sb.append(Contants.AGENT_HOST_UUID); + sb.append(Contants.COMMON_MSG_SEPRATOR); + sb.append(isLoop); + sb.append(Contants.COMMON_MSG_SEPRATOR); + sb.append(startTime.getTime()); + sb.append(Contants.COMMON_MSG_SEPRATOR); + sb.append(endTime.getTime()); + sb.append(Contants.COMMON_MSG_SEPRATOR); + sb.append(resultConfig); + sb.append(Contants.COMMON_MSG_SEPRATOR); + sb.append(resultState); + sb.append(Contants.COMMON_MSG_SEPRATOR); + sb.append(resultDesc); + + return sb.toString(); + } + + public static String getTaskResultFile(long taskType, long taskId){ + return getTaskResultFileNoSuffix(taskType, taskId) + "_" + System.currentTimeMillis() + + Contants.TASK_RESULT_FILE_SUFFIX; + } + + public static String getAgentUpgradeResultTempFile(long taskType, long taskId){ + return getTaskResultFileNoSuffix(taskType, taskId) + + Contants.TASK_RESULT_AGENTTMPFILE_SUFFIX; + } + + private static String getTaskResultFileNoSuffix(long taskType, long taskId){ + return getTaskResultPath() + File.separator + "tasktype" + taskType + "_" + taskId; + } + + public static String getTaskResultPath(){ + return Contants.localTaskResultPath; + } +} diff --git a/src/com/nis/nmsclient/thread/task/TaskReturnHandle.java b/src/com/nis/nmsclient/thread/task/TaskReturnHandle.java new file mode 100644 index 0000000..495df18 --- /dev/null +++ b/src/com/nis/nmsclient/thread/task/TaskReturnHandle.java @@ -0,0 +1,351 @@ +package com.nis.nmsclient.thread.task; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +import net.sf.json.JSONObject; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + +import com.nis.nmsclient.common.Common; +import com.nis.nmsclient.common.Contants; +import com.nis.nmsclient.model.ReturnFilePO; +import com.nis.nmsclient.thread.socket.CommonSocket; +import com.nis.nmsclient.util.CompressFileMgr; +import com.nis.nmsclient.util.FileWrUtil; +import com.nis.nmsclient.util.Utils; + +public class TaskReturnHandle { + Logger logger = Logger.getLogger(TaskReturnHandle.class); + + /*public void sendAllTaskReturnFile(){ + try { + //针对回传文件过多时打包上传未完成的文件继续上传 + File taskDir = new File(Contants.localTaskPath); + if (!taskDir.exists()) { + return; + } + File[] zipArr = FileUtil.getFilesEndWith(taskDir, ".zip"); + if (zipArr != null && zipArr.length > 0) { + for (File file : zipArr) { + if (!file.getName().startsWith(CommonSocket.BP_TYPE_TASK_RETURN)) { + continue; + } + Future future = Common.service.submit(new SSLClient(Thread.currentThread() + .getName(), CommonSocket.REQ_BP_UPLOAD_FIFE, + new String[] { CommonSocket.BP_TYPE_TASK_RETURN, + file.getAbsolutePath() })); + future.get(); + } + } + //---------------------------------- + + File returnDir = new File(Contants.localTaskReturnPath); + if(!returnDir.exists()){ + return; + } + File[] fileArr = FileUtil.getFilesEndWith(returnDir, Contants.TASK_RETURN_FILE_SUFFIX); + if(fileArr == null || fileArr.length == 0){ + return; + } + //--- 将所有任务的回传文件及回传信息保存文件一起打包,发送 + if(fileArr.length > Contants.COMMON_MAX_RETURN_CNT){ + //与Server通信 + Future serFuture = Common.service.submit(new SSLClient( + Thread.currentThread().getName(), + CommonSocket.REQ_HAND_SHAKE, null)); + if (!Contants.isSucessByResult((String) serFuture.get())) { + return; + } + //压缩并删除原文件 + String compressFileStr = Contants.localTaskPath + + File.separator + + CommonSocket.addTimeTagForFileName(CommonSocket.BP_TYPE_TASK_RETURN, + null) + + ".zip"; + ZipUtil.zipWithDelFile(returnDir.listFiles(), compressFileStr, false); + //发送 + Future future = Common.service.submit(new SSLClient(Thread.currentThread() + .getName(), CommonSocket.REQ_BP_UPLOAD_FIFE, + new String[] { CommonSocket.BP_TYPE_TASK_RETURN, + compressFileStr })); + future.get(); + }else{//-- 按正常的一个任务一个任务的回传 + fileArr = FileUtil.sortASCByModify(fileArr); //修改日期升序排序 + for(File file : fileArr){ + if(!file.exists() || !file.isFile()){ + continue; + } + String[] resultArr = FileWrUtil.cfgFileReader(file); + if (resultArr != null && resultArr.length > 0) { + JSONObject jsonObject = JSONObject.fromObject(resultArr[0]); + ReturnFilePO rfPo = (ReturnFilePO) JSONObject.toBean(jsonObject, ReturnFilePO.class); + sendTaskReturnFile(rfPo); + }else{ + //file.delete_bak(); + //使用删除文件公共方法 + FileUtil.delDir(file); + logger.debug("TaskReturnHadle.sendAllTaskReturnFile()()任务回传临时文件(记录任务结果信息)删除:"+file.getAbsolutePath()); + + } + } + } + } catch (Exception e) { + logger.error(Utils.printExceptionStack(e)); + } + }*/ + + public static void startTaskReturnFileThread(final ReturnFilePO rfPo, final List filePaths) { + Common.service.execute(new Runnable() { + @Override + public void run() { + Thread.currentThread().setName("Backpass File Processing ID:" + rfPo.getTaskId()); + TaskReturnHandle tReturnHandle = new TaskReturnHandle(); + ReturnFilePO rfPo2 = tReturnHandle.taskReturnFileHandle(rfPo, filePaths); + //tReturnHandle.sendTaskReturnFile(rfPo2); + } + }); + } + + /** + * 回传文件的统一处理:将回传文件移动到统一回传位置,处理后一个任务只有一个回传文件,修改回传文件名,将任务回传信息写入文件 + */ + public ReturnFilePO taskReturnFileHandle(ReturnFilePO rfPo, List filePaths){ + if(rfPo==null || filePaths==null || filePaths.size()<=0){ + logger.warn("No return file, no return"); + return null; + } + File tempDir = null; + try { + File file = new File(getTaskReturnFile(rfPo.getTaskType(), + rfPo.getTaskId(), rfPo.getIsLoop())); + if (file.exists() && file.length()>0) {// 如果存在,说明之前已经整理过回传文件了,本次不做操作 + return null; + }else if(!file.getParentFile().exists()){// 创建回传文件目录 + file.getParentFile().mkdirs(); + } + + StringBuffer sb = new StringBuffer(); + tempDir = new File(Contants.localTempPath + File.separator + + "return_" + rfPo.getTaskId()); + if(!tempDir.exists()){ + tempDir.mkdirs(); + } + /** + * 处理回传文件:1、过滤不存在或文件路径为空的文件 2、对文件重命名移动到临时目录 + */ + for(String returnPath: filePaths){ + if (StringUtils.isEmpty(returnPath)) { +// sb.append("回传“" + returnPath + "”失败,回传文件路径值为空;"); +// sb.append("Backpass“" + returnPath + "” failed, the return file path value is empty;"); + sb.append("i18n_client.TaskReturnHandle.backpass_n81i“" + returnPath + "” i18n_client.TaskReturnHandle.backFail1_n81i;"); + continue; + } + File returnFile = new File(returnPath); + if (!returnFile.exists()) { +// sb.append("Backpass“" + returnPath + "” failed, return file does not exist;"); + sb.append("i18n_client.TaskReturnHandle.backpass_n81i“" + returnPath + "” i18n_client.TaskReturnHandle.backFail2_n81i;"); + continue; + } + //回传文件取别名:原文件名_T任务ID_时间戳 + String aliasName = CommonSocket.addTimeTagForFileName( + returnFile.getName(), "T" + rfPo.getTaskId(), returnFile.isFile()); + //---- 移动回传文件到临时目录,并重命名为:原文件名_T任务ID_时间戳 + File returnTmpFile = new File(tempDir.getCanonicalPath() + + File.separator + + aliasName); + if (returnFile.isDirectory()) { + FileUtils.copyDirectory(returnFile, returnTmpFile); + } else { + FileUtils.copyFile(returnFile, returnTmpFile); + } + } + + /** + * 将回传的所有文件压缩放到统一回传位置 + */ + String returnFileName = null; + //---- 若回传文件的个数等于1,则把临时目录下的一个文件:按文件夹的话压缩到统一回传位置,文件的话直接移动到统一回传位置 + File[] files = tempDir.listFiles(); + if(files.length==1){ + returnFileName = files[0].getName(); + File destFile = new File(Contants.localTaskReturnPath + File.separator + files[0].getName()); + if (files[0].isDirectory()) { + String compressFileStr = destFile.getAbsolutePath() + CompressFileMgr.getCompressSuffixByOs(false); + returnFileName = new File(compressFileStr).getName(); + new CompressFileMgr().compressFile(files[0] + .getAbsolutePath(), compressFileStr, null, false); + } else { + FileUtils.copyFile(files[0], destFile, false);// 复制并修改文件日期 + } + }else if(files.length > 1){//---- 若回传文件的个数大于1,则把临时目录整个压缩到统一回传位置 + String compressFileStr = Contants.localTaskReturnPath + File.separator + tempDir.getName() + CompressFileMgr.getCompressSuffixByOs(false); + returnFileName = new File(compressFileStr).getName(); + new CompressFileMgr().compressFile(tempDir + .getAbsolutePath(), compressFileStr, null, false); + } + + rfPo.setReturnFileName(returnFileName); + rfPo.setResDesc(sb.toString()); + + /** + * 将信息写入文件 + */ + if (!file.exists()) { + String[] values = new String[] { JSONObject.fromObject( + rfPo).toString() }; + FileWrUtil.cfgFilePrinter(file, Contants.charset, + values); + } + + return rfPo; + } catch (Exception e) { + logger.error("Handling backpass file exceptions:" + Utils.printExceptionStack(e)); + return null; + } finally { + if(tempDir!=null && tempDir.exists()){ + try { + logger.debug("删除临时目录--" + tempDir.getAbsolutePath()); + FileUtils.deleteDirectory(tempDir); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + } + + /** + * 回传文件:先将信息写入临时文件,再判断与Server端通信是否成功 + * 1、通信成功:回传文件,发送最终结果;删除临时文件 + * 2、通信失败:保留临时文件,直接返回 + * @param rfPo 回传文件实体类 + */ + /*public void sendTaskReturnFile(ReturnFilePO rfPo) { + if(rfPo==null){ + logger.debug("回传文件实体对象为空, 不用回传"); + return; + } + try { + File file = new File(getTaskReturnFile(rfPo.getTaskType(), + rfPo.getTaskId())); + + //--回传文件名和回传描述信息均为空时,则无回传文件 + if(StringUtil.isEmpty(rfPo.getReturnFileName()) && StringUtil.isEmpty(rfPo.getResDesc())){ + logger.warn("无回传文件, 不用回传"); + if(file.exists()){ + //file.delete_bak(); + //使用删除文件公共方法 + FileUtil.delDir(file); + logger.debug("TaskReturnHandle.sendTaskReturnFile()成功发送任务回传文件后删除:"+file.getAbsolutePath()); + } + return; + } + //--回传文件名为空,但回传描述信息不为空,则进行步骤4发送任务结果、删除文件 + + *//** + * 步骤1、将信息写入文件 + *//* + if (!file.exists()) { + String[] values = new String[] { JSONObject.fromObject( + rfPo).toString() }; + FileWrUtil.cfgFilePrinter(file, Contants.charset, + values); + } + *//** + * 步骤2、与Server通信 + *//* + Future serFuture = Common.service.submit(new SSLClient( + Thread.currentThread().getName(), + CommonSocket.REQ_HAND_SHAKE, null)); + if (!Contants.isSucessByResult((String) serFuture.get())) { + return; + } + *//** + * 步骤3、回传文件 + *//* + StringBuffer sb = new StringBuffer(); + if(rfPo.getResDesc()!=null){//取已有的结果描述信息 + sb.append(rfPo.getResDesc()); + } + //准备回传文件,回传文件名不为空即有回传的文件时,再回传 + boolean success = false; + if(rfPo.getReturnFileName()!=null && rfPo.getReturnFileName().trim().length()>0){ + for(int i=0; i future = Common.service.submit(new SSLClient( + Thread.currentThread().getName(), + CommonSocket.REQ_TASK_RETURNFILE, rfPo)); + String msg = (String) future.get(); + success = Contants.isSucessByResult(msg); + if(success){ + sb.append("回传成功;"); + break; + } + + try {// 如果更新失败,让当前线程暂停几秒,再重试 + Thread.sleep(1000 * Contants.max_delay_seconds); + } catch (InterruptedException e) { + logger.error(Utils.printExceptionStack(e)); + continue; + } + } + }else{ + success = true; + } + + *//** + * 步骤4、判断文件是否回传完成 + *//* + if(success){ + *//** + * 步骤4-1、发送任务结果 + *//* + TaskResultOper.sendTaskResult(rfPo.getTaskId(), rfPo.getTaskType(), + rfPo.getState(), sb.toString(), "", rfPo.getStartTime(), + rfPo.getEndTime(), false, rfPo.getIsLoop()); + *//** + * 步骤4-2、删除保存回传文件信息的文件 + *//* + if(file.exists()){ + //file.delete_bak(); + //使用删除文件公共方法 + FileUtil.delDir(file); + logger.debug("TaskReturnHandle.sendTaskReturnFile()删除保存回传文件信息的文件:"+file.getAbsolutePath()); + } + *//** + * 步骤4-3、正常回传完成,删除文件 + *//* + File curReturnFile = new File(Contants.localTaskReturnPath + File.separator + rfPo.getReturnFileName()); + if(curReturnFile.exists()){ + //curReturnFile.delete_bak(); + //使用删除文件公共方法 + FileUtil.delDir(curReturnFile); + logger.debug("TaskReturnHandle.sendTaskReturnFile()正常回传完成,删除文件:"+curReturnFile.getAbsolutePath()); + } + } + } catch (Exception e) { + logger.error(Utils.printExceptionStack(e)); + } + }*/ + + /** + * 取任务回传临时记录任务信息文件的文件名: 若是周期任务,加时间后缀taskreturn_taskId_taskType_time.return;若未周期任务, taskreturn_taskId_taskType.return + */ + public static String getTaskReturnFile(long taskType, long taskId, long isLoop) { + //isLoop 是否周期任务: 0 非周期, 1 周期 + if(isLoop==0){ + return Contants.localTaskReturnPath + File.separator + "tasktype" + + taskType + "_" + taskId + + Contants.TASK_RETURN_FILE_SUFFIX; + }else{ + return Contants.localTaskReturnPath + File.separator + "tasktype" + + taskType + "_" + taskId + "_" + + System.currentTimeMillis() + + Contants.TASK_RETURN_FILE_SUFFIX; + } + + } +} diff --git a/src/com/nis/nmsclient/thread/timer/DelLocalFileThread.java b/src/com/nis/nmsclient/thread/timer/DelLocalFileThread.java new file mode 100644 index 0000000..dd68c3e --- /dev/null +++ b/src/com/nis/nmsclient/thread/timer/DelLocalFileThread.java @@ -0,0 +1,197 @@ +package com.nis.nmsclient.thread.timer; + +import java.io.File; +import java.io.IOException; +import java.util.Date; + +import org.apache.commons.io.FileUtils; +import org.apache.log4j.Logger; + +import com.nis.nmsclient.common.Contants; +import com.nis.nmsclient.util.DateUtil; +import com.nis.nmsclient.util.FileUtil; +import com.nis.nmsclient.util.Utils; +import com.sun.org.apache.bcel.internal.generic.NEW; + +public class DelLocalFileThread implements Runnable { + Logger logger = Logger.getLogger(DelLocalFileThread.class); + private String name; + + public DelLocalFileThread(String name){ + this.name = name; + } + + @Override + public void run() { + Thread.currentThread().setName(name); + delLogFile(); + delDataFile(); + delTempFile(); + delUpgradeFile(); + + } + + /** + * 删除日志文件 + */ + public void delLogFile() { + long curDate = System.currentTimeMillis(); + // 删除指定天数之前的日志文件 + File logs = new File(Contants.localLogsPath); + if (!logs.exists() || !logs.isDirectory()) { + return; + } + for (File f : logs.listFiles()) { + long diff = DateUtil.getDaysFromBeginToEnd(f.lastModified(), + curDate); + + if (f.isFile() && diff > Contants.COMMON_DEL_LOG_DAYS) { + //f.delete_bak(); + //使用删除文件公共方法 + FileUtil.delDir(f); + logger.info("删除日志文件" + f.getAbsolutePath()); + //FileUtil.checkParentDirExist(f); + } + } + + } + + /** + * 清理数据文件(包括监测数据和任务文件) + */ + public void delDataFile(){ + long curDateMillis = System.currentTimeMillis(); + // == 1、删除指定分钟之前的所有监测文件 + File doneFile = new File(Contants.localDataDonePath); + if (doneFile.exists()) { + //---删除打包上传的数据 + long timeMillis = curDateMillis - Contants.COMMON_DEL_DATA_HOURS + * 60 * 60 * 1000; + File[] files = FileUtil.getFilesEndWithBeforeMillis(doneFile, ".zip", + timeMillis); + if (files != null && files.length > 0) { + for (File f : files) { + FileUtil.delDir(f); + logger.debug("delDataFile 删除打包文件--" + f.getAbsolutePath()); + } + } + //---删除正常上传的数据文件 + File[] doneDirs = FileUtil.getDirectoryArray(doneFile); + delDataFileCallBack(curDateMillis, doneDirs, Contants.COMMON_DEL_DATA_HOURS); + } + File errorFile = new File(Contants.localDataErrorPath); + if (errorFile.exists()) { + File[] errorDirs = FileUtil.getDirectoryArray(errorFile); + delDataFileCallBack(curDateMillis, errorDirs, Contants.COMMON_DEL_DATA_HOURS); + } + + // == 2、删除指定分钟之前的所有任务相关的文件 + doneFile = new File(Contants.localTaskDonePath); + if (doneFile.exists()) { + //---删除打包上传的任务结果和回传文件 + long timeMillis = curDateMillis - Contants.COMMON_DEL_TASK_HOURS + * 60 * 60 * 1000; + File[] files = FileUtil.getFilesEndWithBeforeMillis(doneFile, ".zip", + timeMillis); + if (files != null && files.length > 0) { + for (File f : files) { + FileUtil.delDir(f); + logger.debug("delDataFile 删除打包文件2--" + f.getAbsolutePath()); + } + } + //---删除正常上传的任务结果和回传文件 + File[] doneDirs = FileUtil.getDirectoryArray(doneFile); + delDataFileCallBack(curDateMillis, doneDirs, Contants.COMMON_DEL_TASK_HOURS); + } + errorFile = new File(Contants.localTaskErrorPath); + if (errorFile.exists()) { + File[] errorDirs = FileUtil.getDirectoryArray(errorFile); + delDataFileCallBack(curDateMillis, errorDirs, Contants.COMMON_DEL_TASK_HOURS); + } + } + + /** + * 清理数据文件的递归回调函数 + */ + public void delDataFileCallBack(long curDateMillis, File[] dirs, int delHours) { + if (dirs == null || dirs.length == 0) { + return; + } + for (File dir : dirs) { + long timeMillis = curDateMillis - delHours + * 60 * 60 * 1000; + File[] sonDirs = FileUtil.getDirsBeforeDateName(dir, DateUtil + .getStingDate(DateUtil.YYYYMMDD, new Date(timeMillis))); + delDataFileCallBack(curDateMillis, sonDirs, delHours); + + File[] files = FileUtil.getFilesBeforeMillis(dir,timeMillis); + if (files != null && files.length > 0) { + for (File f : files) { + FileUtil.delDir(f); + logger.debug("删除文件--" + f.getAbsolutePath()); + } + } + + if (files == null && files.length > 0) { + logger.info("删除文件夹" + dir.getAbsolutePath() + "下的文件:文件" + + files.length + "个"); + } + + if (dir.exists() && dir.listFiles().length <= 0) { + FileUtil.delDir(dir); + logger.info("删除文件夹" + dir.getAbsolutePath()); + } + } + } + + /** + * 清理临时目录的文件 + */ + public void delTempFile() { + try { + long curDate = System.currentTimeMillis(); + // 删除指定日期之前的临时文件 + File temp = new File(Contants.localTempPath); + if (!temp.exists() || !temp.isDirectory()) { + return; + } + for (File f : temp.listFiles()) { + long diff = DateUtil.getDaysFromBeginToEnd(f.lastModified(), + curDate); + if (f.exists() && diff > Contants.COMMON_DEL_TEMP_DAYS) { + //使用删除文件公共方法 + FileUtil.delDir(f); + logger.info("删除临时文件或文件夹" + f.getAbsolutePath()); + } + } + } catch (Exception e) { + logger.error(Utils.printExceptionStack(e)); + } + } + + /** + * 清理UPLOAD目录下的文件 + */ + public void delUpgradeFile() { + try { + long curDate = System.currentTimeMillis(); + // 删除指定日期之前的升级文件 + File uploads = new File(Contants.localUploadsPath); + if (!uploads.exists() || !uploads.isDirectory()) { + return; + } + for (File f : uploads.listFiles()) { + long diff = DateUtil.getDaysFromBeginToEnd(f.lastModified(), + curDate); + if (f.exists() && diff > Contants.COMMON_DEL_UPGRADEFILE_DAYS) { + //使用删除文件公共方法 + FileUtil.delDir(f); + logger.info("删除升级文件或文件夹" + f.getAbsolutePath()); + } + } + } catch (Exception e) { + logger.error(Utils.printExceptionStack(e)); + } + + } +} diff --git a/src/com/nis/nmsclient/thread/upload/BusinessType.java b/src/com/nis/nmsclient/thread/upload/BusinessType.java new file mode 100644 index 0000000..35cd052 --- /dev/null +++ b/src/com/nis/nmsclient/thread/upload/BusinessType.java @@ -0,0 +1,41 @@ +package com.nis.nmsclient.thread.upload; + +/** + * 消息类型 + * @author nanfang + * + */ +public enum BusinessType { + + HeartBeat("HeartBeat",0),//心跳 + DetectZip("DetectZip",1), // 监测数据zip + DetectData("DetectData",2),// 监测数据 + ObjTaskResult("ObjTaskResult",3),//任务结果 + FileTaskReturn("FileTaskReturn",4);//回传文件 + + + private final String name; + private final int type; + + private BusinessType(String name ,int type) { + this.type = type; + this.name = name; + } + + public int getType() { + return this.type; + } + + public String getName(){ + return this.name; + } + + public static BusinessType getType(int type) { + for (BusinessType t : BusinessType.values()) { + if (t.getType() == type) { + return t; + } + } + return null; + } +} \ No newline at end of file diff --git a/src/com/nis/nmsclient/thread/upload/DataSendThread.java b/src/com/nis/nmsclient/thread/upload/DataSendThread.java new file mode 100644 index 0000000..bb51d43 --- /dev/null +++ b/src/com/nis/nmsclient/thread/upload/DataSendThread.java @@ -0,0 +1,589 @@ +package com.nis.nmsclient.thread.upload; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.net.Socket; +import java.net.SocketException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLException; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; + +import org.apache.commons.io.IOUtils; +import org.apache.log4j.Logger; + +import com.nis.nmsclient.common.Common; +import com.nis.nmsclient.common.Contants; +import com.nis.nmsclient.common.StopWatch; +import com.nis.nmsclient.model.ReturnFilePO; +import com.nis.nmsclient.thread.socket.CommonSocket; +import com.nis.nmsclient.thread.socket.SSLCertOper; +import com.nis.nmsclient.thread.task.TaskResultOper; +import com.nis.nmsclient.util.DateUtil; +import com.nis.nmsclient.util.FileUtil; +import com.nis.nmsclient.util.FileWrUtil; +import com.nis.nmsclient.util.StringUtil; +import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream; + +import net.sf.json.JSONObject; + +/** + * 数据发送线程 + * 1、暂时只发送监测数据,csv或zip + * 2、间隔 10 秒启动一次,同时具备心跳的功能 + * 3、实现断线重连 + * @author dell + * + */ +public class DataSendThread implements Runnable{ + public static final Logger logger = Logger.getLogger(DataSendThread.class); + private Socket socket; + private OutputStream os; + private InputStream is; + private String host; + private int port; + + public DataSendThread(String host,int port) { + this.host = host; + this.port = port; + } + + + public void init() throws Exception { + SSLContext ctx = SSLCertOper.getSSLContext(); + SSLSocketFactory ssf = ctx.getSocketFactory(); + socket = (SSLSocket) ssf.createSocket(host,port); + logger.debug("create socket success."); + + //2014-1-23 hyx 如果建立socket成功,但是startHandshake握手失败,且未设置超时时间时,则会一直阻塞 + socket.setSoTimeout(1000 * 60 * Contants.SOCKET_TIMEOUT_MINUTES); + ((SSLSocket) socket).startHandshake(); + logger.debug("handshake success."); + os = socket.getOutputStream(); + is = socket.getInputStream(); + } + + + @Override + public void run() { + Thread.currentThread().setName("DataSendThread"); + logger.debug("开始"); + StopWatch sw = new StopWatch(); + sw.start(); + try { + //重连 + if(socket == null || socket.isClosed()|| !socket.isConnected()|| os == null || is ==null ){ + init(); + } + //发送心跳 + sendHeartBeat(); + //发送监测数据 + sendDetectData(); + //发送任务回传文件 + sendTaskReturnFile(); + //发送任务结果 + sendTaskResult(); + + } catch (SSLException | SocketException e){ + logger.error("SocketException|SSLException",e); + try { + init(); + } catch (Exception e1) { } + } catch (Exception e) { + logger.error("",e); + } + sw.end(); + logger.debug("耗时:"+sw.toString(sw.total())); + logger.debug("结束"); + } + + + + /** + * 发送监测数据 + */ + private void sendDetectData(){ + StopWatch sw = new StopWatch(); + try { + File dataDir = new File(Contants.localDataFilePath); + if (!dataDir.exists()) { + logger.warn("数据目录 : " + dataDir.getAbsolutePath() + " 不存在!!!"); + } else{ + long total = 0; + List allFiles = new ArrayList(); + File[] dataDirs = FileUtil.getDirectoryArray(dataDir); + // ---- 数据处理 + total = handleNullDataFile(allFiles, dataDirs); + logger.info("本次收集监测数据文件总数:" + total + ", 正常数据:" + allFiles.size() + ", 空数据:" + (total - allFiles.size())); + total = allFiles.size();// 正常的要上传的数据个数 + + if(total > 0){ + for (int i = 0; i < total; i++) { + File tem = allFiles.get(i); + this.sendData(tem, BusinessType.DetectData); + String res = this.readLine(); + if(CommonSocket.SUCCESS.equalsIgnoreCase(res)){//发送成功 + this.moveDetecDataToDateDir(tem); + } + } + } + } + } catch (Exception e) { + logger.error("",e); + } + sw.end(); + logger.debug("耗时:"+sw.toString(sw.total())); + logger.debug("结束"); + } + + + /** + * 发送任务结果 + */ + private void sendTaskResult() { + StopWatch sw = new StopWatch(); + try { + logger.debug("传送任务结果开始 ~~~~~~~"); + long startTime = System.currentTimeMillis(); + // == 1、针对结果文件过多时打包上传未完成的文件继续上传 + File taskDir = new File(Contants.localTaskPath); + if (!taskDir.exists()) { + return; + } + + // == 2、检查当前结果文件数量,批量发送文件或打包上传 + File resultDir = new File(TaskResultOper.getTaskResultPath()); + if(!resultDir.exists()){ + return; + } + // == 3 + File[] fileArr = FileUtil.getFilesEndWith(resultDir, Contants.TASK_RESULT_FILE_SUFFIX); + fileArr = FileUtil.sortASCByFileName(fileArr); + List results = new LinkedList(); + StringBuffer sb = new StringBuffer(); + for(File file : fileArr){ + sb.delete(0, sb.length()); + if(!file.exists() || !file.isFile()){ + continue; + } + String[] resultArr = FileWrUtil.cfgFileReader(file); + if(resultArr!=null && resultArr.length>0){ + for(String res : resultArr){ + sb.append(res + ";"); + } + sb.deleteCharAt(sb.length()-1); + results.add(sb.toString()); + } + } + if(results.size() >0 ){ + logger.debug("sendTaskResult-->" + Arrays.toString(results.toArray())); + //发送任务结果请求 + this.sendObject(results, BusinessType.ObjTaskResult); + String res = this.readLine(); + if (CommonSocket.SUCCESS.equalsIgnoreCase(res)) { + // 移动上传成功的任务结果到指定日期目录 + moveTaskResultToDateDir(fileArr); + } + } + sw.end(); + logger.info("本次收集传送任务结果总数:" + fileArr.length + ",用时:" + sw.toString(sw.total())); + } catch (Exception e) { + logger.error("",e); + } + logger.debug("结束"); + } + + + private void sendTaskReturnFile(){ + StopWatch sw = new StopWatch(); + logger.debug("传送回传文件开始 ~~~~~~~"); + try { + // == 1、针对回传文件过多时打包上传未完成的文件继续上传 + File taskDir = new File(Contants.localTaskPath); + if (!taskDir.exists()) { + return; + } + + // == 2、检查当前回传文件数量,单个发送文件或打包上传 + File returnDir = new File(Contants.localTaskReturnPath); + if(!returnDir.exists()){ + return; + } + File[] fileArr = FileUtil.getFilesEndWith(returnDir, Contants.TASK_RETURN_FILE_SUFFIX); + if(fileArr == null || fileArr.length == 0){ + return; + } + + // == 3、发送 + fileArr = FileUtil.sortASCByModify(fileArr); //修改日期升序排序 + for(File file : fileArr){ + if(!file.exists() || !file.isFile()){ + continue; + } + String[] resultArr = FileWrUtil.cfgFileReader(file); + if (resultArr == null || resultArr.length <= 0) { + continue; + } + JSONObject jsonObject = JSONObject.fromObject(resultArr[0]); + ReturnFilePO rfPo = (ReturnFilePO) JSONObject.toBean(jsonObject, ReturnFilePO.class); + + //--回传文件名和回传描述信息均为空时,则无回传文件 + if(StringUtil.isEmpty(rfPo.getReturnFileName()) && StringUtil.isEmpty(rfPo.getResDesc())){ + logger.warn("无回传文件, 不用回传"); + FileUtil.delDir(file); + continue; + } + //--回传文件名为空,但回传描述信息不为空,则进行步骤2发送任务结果、删除文件 + /** + * 步骤1、回传文件 + */ + StringBuffer sb = new StringBuffer(); + if(rfPo.getResDesc()!=null){//取已有的结果描述信息 + sb.append(rfPo.getResDesc()); + } + //准备回传文件,回传文件名不为空即有回传的文件时,再回传 + if(rfPo.getReturnFileName()!=null && rfPo.getReturnFileName().trim().length()>0){ + //发送回传文件请求 + String msg = TaskResultOper.getTaskResultMsg(rfPo + .getTaskId(), rfPo.getTaskType(), null, null, null, rfPo + .getStartTime(), rfPo.getEndTime(), rfPo.getIsLoop()); + File returnFile = new File(Contants.localTaskReturnPath + File.separator + rfPo.getReturnFileName()); + String res = this.sendReturnFile(msg, returnFile, BusinessType.FileTaskReturn); + if(CommonSocket.SUCCESS.equals(res)){ + /** + * 步骤2-1、发送任务结果 + */ + TaskResultOper.sendTaskResult(rfPo.getTaskId(), rfPo.getTaskType(), + rfPo.getState(), sb.toString(), "", rfPo.getStartTime(), + rfPo.getEndTime(), false, rfPo.getIsLoop()); + /** + * 步骤2-2、移动上传成功的 保存回传文件信息的文件 和 回传文件 到指定日期目录 + */ + moveTaskReturnToDateDir(file, rfPo.getReturnFileName()); + } + } + } + sw.end(); + logger.info("本次收集传送任务回传总数:" + fileArr.length + ",用时:" + sw.toString(sw.total())); + } catch (Exception e) { + logger.error("send Task Return File error",e); + } + logger.debug("结束"); + } + + + + /** + * 发送心跳 + * @throws IOException + */ + private void sendHeartBeat() throws IOException{ + byte[] msg = (System.currentTimeMillis()+"").getBytes(); + int len = msg.length; + int t = BusinessType.HeartBeat.getType(); + os.write(Common.intToByteArray(len)); + os.write(0);//消息类型 + os.write(t);//业务类型 + os.write(msg); + os.flush(); + String res = readLine(); + logger.debug("HeartBeat :" + res); + } + + /*** + * 发送任务回传文件 + * @param msg + * @param file + * @param type + * @throws IOException + */ + private String sendReturnFile(String msg,File file,BusinessType type) throws IOException{ + String name = file.getName(); + byte[] nameByte = name.getBytes(); + if(nameByte.length > Byte.MAX_VALUE){ + throw new IllegalArgumentException("file name too long,max length is 127"); + } + byte[] msgBytes = msg.getBytes(); + int msgLen = msgBytes.length; + int totalLen = (int)file.length() + msgBytes.length +4; + int t = type.getType(); + os.write(Common.intToByteArray(totalLen)); + os.write(nameByte.length);//文件名的长度 + os.write(t);//业务类型 + os.write(nameByte);//文件名 + os.write(Common.intToByteArray(msgLen));//消息头长度 + os.write(msgBytes);//消息头 + FileInputStream fis = null; + try { + fis = new FileInputStream(file); + IOUtils.copy(fis, os);//文件内容 + os.flush(); + } finally { + if(fis != null){ + fis.close(); + } + } + String res = readLine(); + logger.debug("sendReturnFile :" + res); + return res; + } + + private void sendObject(Object data,BusinessType type) throws IOException{ + ByteOutputStream bos = null; + ObjectOutputStream oos = null; + try { + bos = new ByteOutputStream(); + oos = new ObjectOutputStream(bos); + oos.writeObject(data); + byte[] bytes = bos.getBytes(); + int len = bytes.length; + int t = type.getType(); + os.write(Common.intToByteArray(len)); + os.write(0); + os.write(t); + os.write(bytes); + } finally { + if(bos != null){ + bos.close(); + } + if(oos != null){ + oos.close(); + } + } + + } + + /** + * 发送数据 + * @param data + * @param type + * @throws IOException + */ + private void sendData(byte[] data,BusinessType type) throws IOException{ + int len = data.length; + int t = type.getType(); + os.write(Common.intToByteArray(len)); + os.write(0); + os.write(t); + os.write(data); + } + + /** + * 发送数据 + * @param file + * @param bt + * @throws IOException + */ + private void sendData(File file,BusinessType bt) throws IOException{ + int len = (int)file.length(); + int t = bt.getType(); + os.write(Common.intToByteArray(len)); + os.write(0); + os.write(t); + FileInputStream fis = null; + try { + fis = new FileInputStream(file); + IOUtils.copy(fis, os); + os.flush(); + } finally { + if(fis != null){ + fis.close(); + } + } + } + + + /** + * 发送文件 包括 文件名 + * @param file + * @param type + * @throws IOException + */ + private void sendFile(File file ,BusinessType type) throws IOException{ + String name = file.getName(); + byte[] nameByte = name.getBytes(); + if(nameByte.length > Byte.MAX_VALUE){ + throw new IllegalArgumentException("file name too long,max length is 127"); + } + int len = (int)file.length(); + os.write(Common.intToByteArray(len));//文件长度 + os.write(nameByte.length);//文件名长度 + os.write((byte)type.getType());//业务类型 + os.write(name.getBytes());//文件名 + FileInputStream fis = null; + try { + fis = new FileInputStream(file); + IOUtils.copy(fis, os); + os.flush(); + } finally { + if(fis != null){ + fis.close(); + } + } + + String res = readLine(); + logger.debug("HeartBeat :" + res); + } + + private String readLine() throws IOException{ + BufferedReader br = new BufferedReader(new InputStreamReader(is, Contants.charset)); + String str = br.readLine(); + logger.debug("recieve : " + str); + return str; + } + + /** + * 移动上传成功的数据文件到指定日期目录 + * 完整文件到目录:.../done/type_procIden/yyyyMMdd + * 0大小文件到目录: .../error/type_procIden/yyyyMMdd + */ + public static void moveDetecDataToDateDir(File... allFiles){ + if(allFiles==null || allFiles.length==0){ + return; + } + for (File file : allFiles) { + String dirTime = DateUtil.getStingDate( + DateUtil.YYYYMMDD, + new Date(file.lastModified())); + String newDir = ""; + if (file.length() > 0) { + newDir = Contants.localDataDonePath + + File.separator + + file.getParentFile().getName() + + File.separator + dirTime; + } else { + newDir = Contants.localDataErrorPath + + File.separator + + file.getParentFile().getName() + + File.separator + dirTime; + } + // -- 文件移动 + FileUtil.moveFile(file, newDir, true); + } + } + + /** + * 遍历所有准备上传的数据文件,将空数据文件移动到指定目录,并记录所有文件总数 + * @param allFiles 所有非空文件集合 + * @param dataDirs 所有数据目录 + * @return 所有文件个数(包括空文件) + * @throws Exception + */ + private long handleNullDataFile(List allFiles, File[] dataDirs) throws Exception { + long total = 0l; + for(File dir : dataDirs){ + File[] files = FileUtil.getFilesEndWith(dir, ".csv"); + if(files==null || files.length==0){ + continue; + } + files = FileUtil.sortASCByModify(files); // 修改日期升序排序 + total += files.length; + for (File file : files) { + if (file.length() > 0) { + allFiles.add(file); + continue; + } + //--- 处理空文件数据:移动空文件数据到指定日期目录 + String dirTime = DateUtil.getStingDate( + DateUtil.YYYYMMDD, + new Date(file.lastModified())); + String newDir = Contants.localDataErrorPath + + File.separator + + file.getParentFile().getName() + + File.separator + dirTime; + FileUtil.moveFile(file, newDir, true); + } + } + return total; + } + + + /** + * 移动上传成功的任务结果到指定日期目录 + * 完整文件到目录:.../done/result/yyyyMMdd + * 0大小文件到目录: .../error/result/yyyyMMdd + */ + public static void moveTaskResultToDateDir(File... fileArr){ + if(fileArr==null || fileArr.length==0){ + return; + } + for (File file : fileArr) { + String dirTime = DateUtil.getStingDate( + DateUtil.YYYYMMDD, + new Date(file.lastModified())); + String newDir = ""; + if (file.length() > 0) { + newDir = Contants.localTaskDonePath + + File.separator + + file.getParentFile().getName() + + File.separator + dirTime; + } else { + newDir = Contants.localTaskErrorPath + + File.separator + + file.getParentFile().getName() + + File.separator + dirTime; + } + // -- 文件移动 + FileUtil.moveFile(file, newDir, true); + } + } + + /** + * 移动上传成功的 保存回传文件信息的文件 和 回传文件 到指定日期目录 + * 完整文件到目录:.../done/return/yyyyMMdd + * 0大小文件到目录: .../error/return/yyyyMMdd + */ + public static void moveTaskReturnToDateDir(File file, String returnFileName){ + String dirTime = DateUtil.getStingDate( + DateUtil.YYYYMMDD, + new Date(file.lastModified())); + String newDir = Contants.localTaskDonePath + + File.separator + + file.getParentFile().getName() + + File.separator + dirTime; + // -- 文件移动 + FileUtil.moveFile(file, newDir, true);// 保留任务信息的临时文件.return + if(returnFileName!=null && !"".equals(returnFileName)){// 实际回传的文件 + File curReturnFile = new File(Contants.localTaskReturnPath + File.separator + returnFileName); + FileUtil.moveFile(curReturnFile, newDir, true); + } + + } + + + public static void main(String[] args) throws Exception { + + DataSendThread.logger.debug("--------------开始-----------------"); + + int threadSize = 1;//默认开10个线程 + int interval = 10;//间隔 60 s + if(args != null&&args.length >0){ + threadSize = Integer.valueOf(args[0]); + } + if(args != null&&args.length >1){ + interval = Integer.valueOf(args[1]); + } + + ScheduledExecutorService stp = Executors.newScheduledThreadPool(100); + for(int i = 0;i< threadSize;i++){ + DataSendThread dst = new DataSendThread("10.0.6.108", 9527); + stp.scheduleWithFixedDelay(dst, 0, interval, TimeUnit.SECONDS); + } + } + +} diff --git a/src/com/nis/nmsclient/thread/upload/UploadDataThread.java b/src/com/nis/nmsclient/thread/upload/UploadDataThread.java new file mode 100644 index 0000000..e786553 --- /dev/null +++ b/src/com/nis/nmsclient/thread/upload/UploadDataThread.java @@ -0,0 +1,158 @@ +package com.nis.nmsclient.thread.upload; + +import java.io.File; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.concurrent.Future; + +import org.apache.log4j.Logger; + +import com.nis.nmsclient.common.Common; +import com.nis.nmsclient.common.Contants; +import com.nis.nmsclient.thread.socket.CommonSocket; +import com.nis.nmsclient.thread.socket.SSLClient; +import com.nis.nmsclient.util.DateUtil; +import com.nis.nmsclient.util.FileUtil; +import com.nis.nmsclient.util.Utils; +import com.nis.nmsclient.util.ZipUtil; + +/** + * 用于定时扫描并上传监测数据文件【数据收集方式改为DC主动后,此类废弃】 + * + **/ +public class UploadDataThread implements Runnable { + Logger logger = Logger.getLogger(UploadDataThread.class); + private String name; + + public UploadDataThread(String name) { + this.name = name; + } + + public void run() { + long startTime = System.currentTimeMillis(); + Thread.currentThread().setName(name); + logger.debug("上传数据开始 ~~~~~~~"); + try { + //针对数据文件过多时打包上传未完成的文件继续上传 + File parDir = new File(Contants.localDataCollection); + if(!parDir.exists()){ + return; + } + File[] fileArr = FileUtil.getFilesEndWith(parDir, ".zip"); + if (fileArr != null && fileArr.length > 0) { + for (File file : fileArr) { + if (!file.getName().startsWith(CommonSocket.BP_TYPE_DETECT_DATA)) { + continue; + } + Future future = Common.service.submit(new SSLClient(name, + CommonSocket.REQ_BP_UPLOAD_FIFE, new String[] { + CommonSocket.BP_TYPE_DETECT_DATA, + file.getAbsolutePath() })); + future.get(); + } + } + //---------------------------------------- + + File dataDir = new File(Contants.localDataFilePath); + if (!dataDir.exists()) { + logger.warn("Data directory“" + dataDir.getAbsolutePath() + "”Non-existent!!!"); + return; + } + + long total = 0; + List allFiles = new ArrayList(); + File[] dataDirs = FileUtil.getDirectoryArray(dataDir); + for(File dir : dataDirs){ + File[] files = FileUtil.getFilesEndWith(dir, ".csv"); + if(files==null || files.length==0){ + continue; + } + files = FileUtil.sortASCByModify(files); // 修改日期升序排序 + //allFiles.addAll(Arrays.asList(files)); + total += files.length; + for (File file : files) { + if (file.length() > 0) { + allFiles.add(file); + continue; + } + //--- 处理空文件数据:移动空文件数据到指定日期目录 + String dirTime = DateUtil.getStingDate( + DateUtil.YYYYMMDD, + new Date(file.lastModified())); + String newDir = Contants.localDataErrorPath + + File.separator + + file.getParentFile().getName() + + File.separator + dirTime; + FileUtil.moveFile(file, newDir, true); + } + } + logger.info("本次轮循数据文件总数:" + total + ", 正常数据:" + allFiles.size() + ", 空数据:" + (total-allFiles.size())); + total = allFiles.size();//正常的要上传的数据个数 + + //--- 将所有数据文件一起打包,发送 + if(total>Contants.COMMON_ZIP_MIN_SIZE){ + //与Server通信 + Future serFuture = Common.service.submit(new SSLClient( + Thread.currentThread().getName(), + CommonSocket.REQ_HAND_SHAKE, null)); + if (!Contants.isSucessByResult((String) serFuture.get())) { + logger.debug("UploadDataThread--ServerHandShake--fail return"); + return; + } + //压缩并删除原文件 + String compressFileStr = Contants.localDataCollection + + File.separator + + CommonSocket.addTimeTagForFileName( + CommonSocket.BP_TYPE_DETECT_DATA, null, true) + ".zip"; + ZipUtil.zipWithDelFile(dataDirs, compressFileStr, true); + //发送 + Future future = Common.service.submit(new SSLClient( + Thread.currentThread().getName(), + CommonSocket.REQ_BP_UPLOAD_FIFE, new String[]{CommonSocket.BP_TYPE_DETECT_DATA, compressFileStr})); + future.get(); + logger.info("-----本次轮循将所有数据打包上传"); + } else if (total > 0) {// -- 按正常所有监测数据批量上传 + Future future = Common.service.submit(new SSLClient(name, + CommonSocket.REQ_UPLOAD_DATAS, new Object[] { + dataDir.getParent(), allFiles })); + String msg = (String) future.get(); + if (Contants.isSucessByResult(msg)) { + /** + * 移动上传成功的文件到指定日期目录 + * 完整文件到目录:.../done/type_procIden/yyyyMMdd + * 0大小文件到目录: .../error/type_procIden/yyyyMMdd + */ + for (File file : allFiles) { + String dirTime = DateUtil.getStingDate( + DateUtil.YYYYMMDD, + new Date(file.lastModified())); + String newDir = ""; + if (file.length() > 0) { + newDir = Contants.localDataDonePath + + File.separator + + file.getParentFile().getName() + + File.separator + dirTime; + } else { + newDir = Contants.localDataErrorPath + + File.separator + + file.getParentFile().getName() + + File.separator + dirTime; + } + // -- 文件移动 + FileUtil.moveFile(file, newDir, true); + } + } + logger.info("-----本次轮循上传数据总数:" + total + ",用时:" + + (System.currentTimeMillis() - startTime) + "ms"); + }else{ + logger.info("-----本次轮循未上传数据"); + } + + } catch (Exception e) { + logger.error("Upload data exception:" + Utils.printExceptionStack(e)); + } + logger.debug("上传数据结束 ~~~~~~~"); + } + +} \ No newline at end of file diff --git a/src/com/nis/nmsclient/util/CompressFileMgr.java b/src/com/nis/nmsclient/util/CompressFileMgr.java new file mode 100644 index 0000000..3be2549 --- /dev/null +++ b/src/com/nis/nmsclient/util/CompressFileMgr.java @@ -0,0 +1,135 @@ +package com.nis.nmsclient.util; + +import java.io.File; + +import org.apache.log4j.Logger; + +import com.nis.nmsclient.util.GzipUtil; +import com.nis.nmsclient.util.RarUtil; +import com.nis.nmsclient.util.ZipUtil; + +/** + * 文件解压缩的统一处理 + * @date Mar 20, 2012 + * @version + */ +public class CompressFileMgr { + static Logger logger = Logger.getLogger(CompressFileMgr.class); + + /** + * 文件压缩 + * @param sourcePath 源文件或目录 + * @param destFile 压缩后的文件 + * @param excludes 源目录中不要压缩的文件列表 + * @param isAbs 相对路径还是绝对路径压缩 + * @return + * @throws Exception + */ + public boolean compressFile(String sourcePath, String destFile, + String[] excludes, boolean isAbs) throws Exception { + boolean returnFlag = true; + File folder = new File(sourcePath); + if (!folder.exists()) { + return false; + } + if (destFile.length() == (destFile.lastIndexOf(".zip") + 4)) {// 判断是否zip包 + ZipUtil.zip(sourcePath, destFile, excludes); + } else if (destFile.length() == (destFile.lastIndexOf(".gz") + 3)) {// 判断是否gzip包 + GzipUtil.gzipByCmd(sourcePath, destFile, excludes, isAbs); + } else if (destFile.length() == (destFile.lastIndexOf(".tar") + 4)) {// 判断是否tar包 + GzipUtil.tarByCmd(sourcePath, destFile, excludes, isAbs); + } else { + throw new Exception("unable to compress this compressed file"); + } + + return returnFlag; + } + + /** + * 文件解压,如果sourcePath是一个目录,则解压它下面的所有压缩文件 + * @param sourcePath 需要解压的文件或需要解压文件的目录 + * @param destPath 解压到的目标路径 + * @param isAbs 相对路径还是绝对路径解压 + * @return + * @throws Exception + */ + public boolean decompressFile(String sourcePath, String destPath, boolean isAbs) + throws Exception { + logger.debug("decompressFile start……"); + boolean returnFlag = true; + logger.debug("decompressFile sourcePath-----" + sourcePath); + logger.debug("decompressFile destPath-----" + destPath); + File folder = new File(sourcePath); + if (!folder.exists()) { + return false; + } + if (folder.isDirectory()) { + String files[] = folder.list(); + String fileAbs = null; + for (int i = 0; i < files.length; i++) { + fileAbs = sourcePath + File.separator + files[i]; + decompressFile(fileAbs, destPath, isAbs); + } + } else { + decompress(sourcePath, destPath, isAbs); + } + + logger.debug("decompressFile end!"); + return returnFlag; + } + + /** + * 解压文件,只针对单个压缩文件 + * @param sourceFile 需要解压的文件 + * @param destPath 解压到的目标路径 + * @param isAbs 相对路径还是绝对路径解压 + * @throws Exception + */ + private void decompress(String sourceFile, String destPath, boolean isAbs) + throws Exception { + logger.debug("decompress start……"); + logger.debug("decompress sourceFile---" + sourceFile); + logger.debug("decompress 1-----"+(sourceFile.length() == (sourceFile.lastIndexOf(".zip") + 4))); + logger.debug("decompress 2-----"+(sourceFile.length() == (sourceFile.lastIndexOf(".rar") + 4))); + logger.debug("decompress 3-----"+(sourceFile.length() == (sourceFile.lastIndexOf(".gz") + 3))); + if (sourceFile.length() == (sourceFile.lastIndexOf(".zip") + 4)) {// 判断是否zip包 + ZipUtil.unZip(sourceFile, destPath); + } else if (sourceFile.length() == (sourceFile.lastIndexOf(".rar") + 4)) {// 判断是否rar包 + RarUtil.unRar(sourceFile, destPath); + } else if (sourceFile.length() == (sourceFile.lastIndexOf(".gz") + 3)) {// 判断是否gzip包 + GzipUtil.unGzipByCmd(sourceFile, destPath, isAbs); + } else if (sourceFile.length() == (sourceFile.lastIndexOf(".tar") + 4)) {// 判断是否tar包 + GzipUtil.unTarByCmd(sourceFile, destPath, isAbs); + } else { + throw new Exception("unable to decompress this decompressed file"); + } + logger.debug("decompress end!"); + } + + public static String getCompressSuffixByOs(boolean isAbs){ + String suffix = ".zip"; + //根据操作系统确定获取进程ID的方式 + String os = System.getProperty("os.name"); + if (os.startsWith("Windows")) { + suffix = ".zip"; + }else if (os.startsWith("Linux")){ + suffix = (isAbs ? "_absolute" : "_relative") + ".tar.gz"; + } + return suffix; + } + + public static boolean isCompressFile(File file){ + boolean flag = false; + if(file.isFile()){ + String fileName = file.getName(); + if (".rar".equalsIgnoreCase(fileName.substring(fileName.length() - 4)) + || ".zip".equalsIgnoreCase(fileName.substring(fileName.length() - 4)) + || ".tar".equalsIgnoreCase(fileName.substring(fileName.length() - 4)) + || ".gz".equalsIgnoreCase(fileName.substring(fileName.length() - 3))) { + flag = true; + } + } + return flag; + + } +} diff --git a/src/com/nis/nmsclient/util/DESUtil.java b/src/com/nis/nmsclient/util/DESUtil.java new file mode 100644 index 0000000..a93b11f --- /dev/null +++ b/src/com/nis/nmsclient/util/DESUtil.java @@ -0,0 +1,83 @@ +package com.nis.nmsclient.util; + +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.DESKeySpec; +import javax.crypto.spec.IvParameterSpec; + +import sun.misc.BASE64Decoder; +import sun.misc.BASE64Encoder; + +/** + * 通过DES加密解密实现一个String字符串的加密和解密. + * + */ +public class DESUtil { + private final static String key = "longstar"; + + /** + * DES加密方法 + * + */ + public static String desEncrypt(String message) throws Exception { + Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); + + DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("ASCII")); + + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); + SecretKey secretKey = keyFactory.generateSecret(desKeySpec); + IvParameterSpec iv = new IvParameterSpec(key.getBytes("ASCII")); + cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv); + + byte data[] = message.getBytes("ASCII"); + byte[] encryptedData = cipher.doFinal(data); + + return getBASE64(encryptedData); + } + + /** + * DES解密方法 + * + */ + public static String desDecrypt(String message) throws Exception { + Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); + + DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("ASCII")); + + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); + SecretKey secretKey = keyFactory.generateSecret(desKeySpec); + IvParameterSpec iv = new IvParameterSpec(key.getBytes("ASCII")); + cipher.init(Cipher.DECRYPT_MODE, secretKey, iv); + + byte data[] = getFromBASE64(message); + byte[] encryptedData = cipher.doFinal(data); + + return new String(encryptedData); + } + + // 对base64编码的string解码成byte数组 + private static byte[] getFromBASE64(String s) { + if (s == null) + return null; + BASE64Decoder decoder = new BASE64Decoder(); + try { + byte[] b = decoder.decodeBuffer(s); + return b; + } catch (Exception e) { + return null; + } + } + + //将 byte数组 进行 BASE64 编码 + private static String getBASE64(byte[] b) { + if (b == null) + return null; + try { + String returnstr = (new BASE64Encoder()).encode(b); + return returnstr; + } catch (Exception e) { + return null; + } + } +} diff --git a/src/com/nis/nmsclient/util/DateUtil.java b/src/com/nis/nmsclient/util/DateUtil.java new file mode 100644 index 0000000..fbc9e0e --- /dev/null +++ b/src/com/nis/nmsclient/util/DateUtil.java @@ -0,0 +1,142 @@ +package com.nis.nmsclient.util; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.apache.log4j.Logger; + +public class DateUtil { + static Logger logger = Logger.getLogger(DateUtil.class); + /** + * 处理日期时,用到参数。格式24小时制yyyy-MM-dd HH:mm:ss + */ + public static final SimpleDateFormat YYYY_MM_DD_HH24_MM_SS = new SimpleDateFormat( + "yyyy-MM-dd HH:mm:ss"); + /** + * 处理日期时,用到参数。格式24小时制yyyyMMddHHmmss + */ + public static final SimpleDateFormat YYYYMMDDHH24MMSS = new SimpleDateFormat( + "yyyyMMddHHmmss"); + /** + * 处理日期时,用到参数。格式为yyyy-MM-dd + */ + public static final SimpleDateFormat YYYY_MM_DD = new SimpleDateFormat( + "yyyy-MM-dd"); + /** + * 处理日期时,用到参数。格式为yyyyMMdd + */ + public static final SimpleDateFormat YYYYMMDD = new SimpleDateFormat( + "yyyyMMdd"); + + + /** + * 获得当前日期 + * + * @return + */ + public static String getCurrentDate(SimpleDateFormat sf) { + if(sf==null){ + sf = YYYY_MM_DD; + } + return sf.format(new Date()); + } + + /** + * 获得某日期的指定格式的字符串 + * @param sf + * @param date + * @return + */ + public static String getStingDate(SimpleDateFormat sf, Date date) { + if(date==null){ + date = new Date(); + } + if(sf==null){ + sf = YYYY_MM_DD; + } + + return sf.format(date); + } + + public static long getDaysFromBeginToEnd(SimpleDateFormat dateFormat, + String begin, String end) { + Date beginD = null; + Date endD = null; + long days = 0; + try { + if (begin != null && !"".equals(begin)) { + beginD = dateFormat.parse(begin); + } else { + beginD = new Date(); + } + if (end != null && !"".equals(end)) { + endD = dateFormat.parse(end); + } else { + endD = new Date(); + } + days = getDaysFromBeginToEnd(beginD, endD); + } catch (ParseException e) { + logger.error(Utils.printExceptionStack(e)); + return days; + } + + return days; + + } + + public static long getDaysFromBeginToEnd(Date begin, Date end) { + long days = 0; + if (begin != null && end != null) { + days = getDaysFromBeginToEnd(begin.getTime(), end.getTime()); + } + + return days; + + } + + public static long getDaysFromBeginToEnd(long begin, long end) { + return (end - begin) / (24 * 60 * 60 * 1000); + } + + public static long getMinutesFromBeginToEnd(SimpleDateFormat dateFormat, + String begin, String end) { + Date beginD = null; + Date endD = null; + long days = 0; + try { + if (begin != null && !"".equals(begin)) { + beginD = dateFormat.parse(begin); + } else { + beginD = new Date(); + } + if (end != null && !"".equals(end)) { + endD = dateFormat.parse(end); + } else { + endD = new Date(); + } + days = getMinutesFromBeginToEnd(beginD, endD); + } catch (ParseException e) { + logger.error(Utils.printExceptionStack(e)); + return days; + } + + return days; + + } + + public static long getMinutesFromBeginToEnd(Date begin, Date end) { + long days = 0; + if (begin != null && end != null) { + days = getMinutesFromBeginToEnd(begin.getTime(), end.getTime()); + } + + return days; + + } + + public static long getMinutesFromBeginToEnd(long begin, long end) { + return (end - begin) / (60 * 1000); + } + +} diff --git a/src/com/nis/nmsclient/util/FileUtil.java b/src/com/nis/nmsclient/util/FileUtil.java new file mode 100644 index 0000000..7f8eee7 --- /dev/null +++ b/src/com/nis/nmsclient/util/FileUtil.java @@ -0,0 +1,477 @@ +package com.nis.nmsclient.util; + +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.util.Arrays; +import java.util.Comparator; + +import org.apache.commons.io.FileUtils; +import org.apache.log4j.Logger; + +import com.nis.nmsclient.common.Contants; + +/** + * 文件操作类:检索、排序 + * + */ +public class FileUtil { + static Logger logger = Logger.getLogger(FileUtil.class); + + /** + * 获取子目录列表 + * @param file + * @return + */ + public static File[] getDirectoryArray(File file) { + if (!file.isDirectory()) { + new Exception(file.getAbsolutePath() + " Not A Directory"); + } + return file.listFiles(new FilenameFilter() { + // 使用匿名内部类重写accept方法; + public boolean accept(File dir, String name) { + if (new File(dir, name).isDirectory()) { + return true; + } else + return false; + } + }); + } + + + /** + * 获取指定全部或部分名称的文件 + * @param file + * @param azz + * @return + */ + public static File[] getFilesArray(File file, final String azz) { + if (!file.isDirectory()) { + new Exception(file.getAbsolutePath() + " Not A Directory"); + } + return file.listFiles(new FilenameFilter() { + // 使用匿名内部类重写accept方法; + public boolean accept(File dir, String name) { + if (new File(dir, name).isDirectory()) { + return false; + } + return name.indexOf(azz) != -1; // 过滤出指定全部名称或部分名称的文件 + } + }); + } + + /** + * 获取指定前缀的文件 + * @param file + * @param suffix + * @return + */ + public static File[] getFilesStartWith(File file, final String prefix) { + if (!file.isDirectory()) { + new Exception(file.getAbsolutePath() + " Not A Directory"); + } + return file.listFiles(new FilenameFilter() { + // 使用匿名内部类重写accept方法; + public boolean accept(File dir, String name) { + if (new File(dir, name).isDirectory()) { + return false; + } + return name.startsWith(prefix); // 过滤出注定前缀名称的文件 + } + }); + } + + /** + * 获取指定时间段指定前缀的文件 + * @param file + * @param suffix + * @return + */ + public static File[] getFilesStartWithByMillis(File file, final String prefix, final long sTimeMillis, final long eTimeMillis) { + if (!file.isDirectory()) { + new Exception(file.getAbsolutePath() + " Not A Directory"); + } + return file.listFiles(new FilenameFilter() { + // 使用匿名内部类重写accept方法; + public boolean accept(File dir, String name) { + if (new File(dir, name).isDirectory()) { + return false; + } + if (sTimeMillis > 0 && eTimeMillis > 0) { + if (new File(dir, name).lastModified() < sTimeMillis + || new File(dir, name).lastModified() > eTimeMillis) {// 不在指定时间段 + return false; + } + } + return name.startsWith(prefix); // 过滤出注定前缀名称的文件 + } + }); + } + + /** + * 获取指定后缀名的文件 + * @param file + * @param suffix + * @return + */ + public static File[] getFilesEndWith(File file, final String suffix) { + if (!file.isDirectory()) { + new Exception(file.getAbsolutePath() + " Not A Directory"); + } + return file.listFiles(new FilenameFilter() { + // 使用匿名内部类重写accept方法; + public boolean accept(File dir, String name) { + if (new File(dir, name).isDirectory()) { + return false; + } + return name.endsWith(suffix); // 过滤出注定后缀名称的文件 + } + }); + } + + /** + * 获取指定时间修改的指定后缀名的文件 + * @param file + * @param suffix + * @return + */ + public static File[] getFilesEndWithBeforeMillis(File file, final String suffix, final long timeMillis) { + if (!file.isDirectory()) { + new Exception(file.getAbsolutePath() + " Not A Directory"); + } + return file.listFiles(new FilenameFilter() { + // 使用匿名内部类重写accept方法; + public boolean accept(File dir, String name) { + if (new File(dir, name).isDirectory() || new File(dir,name).lastModified() > timeMillis) { + return false; + } + return name.endsWith(suffix); // 过滤出注定后缀名称的文件 + } + }); + } + + /** + * 获取指定时间修改的文件 + * @return + */ + public static File[] getFilesBeforeMillis(File file, final long timeMillis) { + if (!file.isDirectory()) { + new Exception(file.getAbsolutePath() + " Not A Directory"); + } + return file.listFiles(new FilenameFilter() { + // 使用匿名内部类重写accept方法; + public boolean accept(File dir, String name) { + if (new File(dir, name).isDirectory() || new File(dir,name).lastModified() > timeMillis) { + return false; + } + return true; + } + }); + } + + /** + * 获取指定毫秒之后修改过的文件 + * @param file + * @param timeMillis + * @return + */ + public static File[] getFilesAfterMillis(File file, final long timeMillis) { + if (!file.isDirectory()) { + new Exception(file.getAbsolutePath() + " Not A Directory"); + } + return file.listFiles(new FilenameFilter() { + // 使用匿名内部类重写accept方法; + public boolean accept(File dir, String name) { + if (new File(dir, name).lastModified() >= timeMillis) { + return true; + } else + return false; + } + }); + } + + /** + * 获取指定时间名称及之前的文件夹 + * @param file + * @param suffix + * @return + */ + public static File[] getDirsBeforeDateName(File file, final String yyyyMMddName) { + if (!file.isDirectory()) { + new Exception(file.getAbsolutePath() + " Not A Directory"); + } + return file.listFiles(new FilenameFilter() { + // 使用匿名内部类重写accept方法; + public boolean accept(File dir, String name) { + if (new File(dir, name).isDirectory() && name.compareTo(yyyyMMddName)<=0) { + return true; + } + return false; + } + }); + } + + /** + * 获取指定时间名称及之后的文件夹 + * @param file + * @param suffix + * @return + */ + public static File[] getDirsAfterDateName(File file, final String yyyyMMddName) { + if (!file.isDirectory()) { + new Exception(file.getAbsolutePath() + " Not A Directory"); + } + return file.listFiles(new FilenameFilter() { + // 使用匿名内部类重写accept方法; + public boolean accept(File dir, String name) { + if (new File(dir, name).isDirectory() && name.compareTo(yyyyMMddName)>=0) { + return true; + } + return false; + } + }); + } + + /** + * 文件数组按最后修改日期排序,升序 + * @param files + * @return + */ + public static File[] sortASCByModify(File[] files) { + Arrays.sort(files, new Comparator(){ + public int compare(File arg0, File arg1) { + if(arg0.lastModified() > arg1.lastModified()){ + return 1; + }else if (arg0.lastModified() < arg1.lastModified()){ + return -1; + }else { + return 0; + } + } + }); + return files; + } + + /** + * 文件数组按最后修改日期排序,降序 + * @param files + * @return + */ + public static File[] sortDescByModify(File[] files) { + Arrays.sort(files, new Comparator(){ + public int compare(File arg0, File arg1) { + if(arg0.lastModified() > arg1.lastModified()){ + return -1; + }else if (arg0.lastModified() < arg1.lastModified()){ + return 1; + }else { + return 0; + } + } + }); + return files; + } + + /** + * 文件数组按名称排序,升序 + * @param files + * @return + */ + public static File [] sortASCByFileName(File[] files) { + Arrays.sort(files, new Comparator(){ + public int compare(File arg0, File arg1) { + return arg0.getName().compareTo(arg1.getName()); + } + }); + return files; + } + /** + * 文件数组按名称排序,降序 + * @param files + * @return + */ + public static File [] sortDescByFileName(File[] files) { + Arrays.sort(files, new Comparator(){ + public int compare(File arg0, File arg1) { + return arg1.getName().compareTo(arg0.getName()); + } + }); + return files; + } + + /** + * 将文件移动到指定文件夹 + * + * @param f + * 源文件 + * @param newDir + * 新目录 + * @param flag + * 是否覆盖 true:覆盖 false:不覆盖 + */ + public static void moveFile(File f, String newDir, boolean flag) { + if (!f.exists()) { + logger.debug("文件已不存在,无法移动!" + f.getAbsolutePath()); + return; + } + File fileDir = new File(newDir); // 备份目录 + if (!fileDir.exists()) { // 检查并创建新目录 + fileDir.mkdirs(); + } + File dtnFile = new File(fileDir.getAbsolutePath() + File.separator + + f.getName()); // 制定目标文件路径以及文件名 + if (dtnFile.exists() && flag) { // 检查并删除已存在文件 + //dtnFile.delete_bak(); + //使用删除文件公共方法 + FileUtil.delDir(dtnFile); + logger.debug("moveFile 删除已存在文件--" + dtnFile.getAbsolutePath()); + //FileUtil.checkParentDirExist(dtnFile); + } + try { + FileUtils.copyFile(f, dtnFile); // 移动文件 + logger.debug("文件 From 》 " + f.getAbsolutePath() + + "\n To 》 " + dtnFile.getAbsolutePath()); + if (f.exists()) { + logger.debug("删除源文件" + f.getAbsolutePath()); + //f.delete_bak(); + //使用删除文件公共方法 + FileUtil.delDir(f); + //FileUtil.checkParentDirExist(f); + } else { + logger.debug("源文件不存在!不用删了!" + f.getAbsolutePath()); + return; + } + } catch (IOException e) { + logger.error(Utils.printExceptionStack(e)); + } + } + + /** + * 删除文件或文件夹 + */ + public static void delDir(File file) { + try {//文件在可删范围并且不在禁删范围 + if (file.exists() && isIncludeDelRange(file) && !isExcludeDelRange(file)) { + if (!file.isDirectory()) { + file.delete(); + logger.debug("FileUtil.delDir(File file)删除文件--" + file.getAbsolutePath()); + FileUtil.checkParentDirExist(file); + } else if (file.isDirectory()) { + delDir2(file); + } + } + } catch (IOException e) { + logger.error(Utils.printExceptionStack(e)); + } + } + + /** + * 递归删除文件夹及其下的所有文件 + */ + private static void delDir2(File file) throws IOException { + if (!file.exists()) { + return; + } + if (!file.isDirectory()) { + file.delete(); + logger.debug("FileUtil.delDir2(File file)删除文件--" + file.getAbsolutePath()); + FileUtil.checkParentDirExist(file); + } else if (file.isDirectory()) { + if (!isExcludeDelRange(file)) {// 文件不在禁删范围 + for (File f : file.listFiles()) { + delDir2(f); + } + file.delete(); + logger.debug("FileUtil.delDir2(File file)删除文件夹--" + file.getAbsolutePath()); + FileUtil.checkParentDirExist(file); + } + } + } + + /** + * 检查文件是否在可删范围内 + * @param file + * @return true:是,false:否 + */ + public static boolean isIncludeDelRange(File file) throws IOException{ + boolean flag = false; + String path = file.getCanonicalPath(); + if(Contants.COMMON_DEL_PATH_INCLUDE!=null){ + for(String include : Contants.COMMON_DEL_PATH_INCLUDE){ + if(path.startsWith(include)){ + flag = true; + break; + } + } + }else{//删除范围参数为空,则返回在删除范围 + flag = true; + } + return flag; + } + + /** + * 检查文件是否在禁删范围内 + * @param file + * @return true:是,false:否 + */ + public static boolean isExcludeDelRange(File file) throws IOException{ + boolean flag = false; + String path = file.getCanonicalPath(); + if(Contants.COMMON_DEL_PATH_EXCLUDE!=null){ + for(String exclude : Contants.COMMON_DEL_PATH_EXCLUDE){ + if(path.startsWith(exclude)){ + flag = true; + break; + } + } + }else{//禁删参数为空,则返回不在禁删范围 + flag = false; + } + return flag; + } + + public static void checkParentDirExist(File file){ + logger.debug("检查父目录是否存在---" +file.getParentFile().exists() + "---" + file.getParent()); + } + + /** + * 格式化处理路径 + * @param path + * @return + */ + public static String handlerPath(String path){ + File file = new File(path); + try { + path = file.getCanonicalPath(); + } catch (IOException e) { + logger.error(Utils.printExceptionStack(e)); + } + + return path; + } + + public static File[] getAll(File dir, int level) { + logger.info(getLevel(level) + dir.getName()); + + level++; + File[] files = dir.listFiles(); + for (int x = 0; x < files.length; x++) { + if (files[x].isDirectory()) + getAll(files[x], level); + else + logger.debug(getLevel(level) + files[x].getName()); + } + return files; + } + + public static String getLevel(int level) { + StringBuilder sb = new StringBuilder(); + sb.append("|--"); + + for (int x = 0; x < level; x++) { + sb.insert(0, "| "); + } + return sb.toString(); + } + +} diff --git a/src/com/nis/nmsclient/util/FileWrUtil.java b/src/com/nis/nmsclient/util/FileWrUtil.java new file mode 100644 index 0000000..8ebf75c --- /dev/null +++ b/src/com/nis/nmsclient/util/FileWrUtil.java @@ -0,0 +1,285 @@ +package com.nis.nmsclient.util; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; + +import com.Ostermiller.util.ExcelCSVParser; +import com.Ostermiller.util.ExcelCSVPrinter; +import com.nis.nmsclient.util.io.UnicodeReader; + +public class FileWrUtil { + static Logger logger = Logger.getLogger(FileWrUtil.class); + + /** + * 根据文件编码添加文件内容前缀 + * @param file + * @param encoding + */ + protected static boolean addFileHeadByEncoding(File file, String encoding) throws Exception{ + FileOutputStream fos = null; + boolean flag = false; + try{ + byte[] head = null; + if("UTF-8".equalsIgnoreCase(encoding)){ + head = new byte[]{(byte)0xEF,(byte)0xBB,(byte)0xBF}; + }else if("UTF-16BE".equalsIgnoreCase(encoding)){ + head = new byte[]{(byte)0xFE,(byte)0xFF}; + }else if("UTF-16LE".equalsIgnoreCase(encoding)){ + head = new byte[]{(byte)0xFF,(byte)0xFE}; + }else if("UTF-32BE".equalsIgnoreCase(encoding)){ + head = new byte[]{(byte)0x00,(byte)0x00,(byte)0xFE,(byte)0xFF}; + }else if("UTF-32LE".equalsIgnoreCase(encoding)){ + head = new byte[]{(byte)0xFF,(byte)0xFF,(byte)0x00,(byte)0x00}; + } + + if(head!=null){ + fos = new FileOutputStream(file); + fos.write(head); + fos.flush(); + + flag = true; + } + } catch (IOException e) { + throw e; + }finally { + if(fos!=null){ + try { + fos.close(); + } catch (IOException e) { + } + } + } + + return flag; + } + + /** + * 写入文件, .cfg\.ini\.txt + * + */ + public static boolean cfgFilePrinter(File file, String charset, String[] values) throws Exception{ + OutputStreamWriter fos = null; + try { + if(addFileHeadByEncoding(file, charset)){ + fos = new OutputStreamWriter( + new FileOutputStream(file,true), charset); + }else{ + fos = new OutputStreamWriter( + new FileOutputStream(file), charset); + } + for(String val : values){ + fos.write(val); + fos.write("\n"); + } + fos.flush(); + } catch (IOException e) { + throw e; + }finally { + if(fos!=null){ + try { + fos.close(); + } catch (IOException e) { + } + } + } + + return true; + } + + /** + * 追加内容到文件, .cfg\.ini\.txt + * + */ + public static boolean cfgFileAppender(File file, String charset, String[] values) throws Exception{ + OutputStreamWriter fos = null; + try { + fos = new OutputStreamWriter( + new FileOutputStream(file, true), charset); + for(String val : values){ + fos.write(val); + fos.write("\n"); + } + fos.flush(); + } catch (IOException e) { + throw e; + }finally { + if(fos!=null){ + try { + fos.close(); + } catch (IOException e) { + } + } + } + + return true; + } + + /** + * 根据文件的编码读取文件内容, .cfg\.ini\.txt + * + */ + public static String[] cfgFileReader(File file) throws Exception{ + BufferedReader br = null; + ArrayList list = new ArrayList(); + try { + + br = new BufferedReader(new UnicodeReader(new FileInputStream( + file), Charset.defaultCharset().name())); + String str = null; + while((str=br.readLine())!=null){ + list.add(str); + } + } catch (IOException e) { + throw e; + }finally { + if(br!=null){ + try { + br.close(); + } catch (IOException e) { + } + } + } + + String[] values = new String[list.size()]; + return list.toArray(values); + } + + /** + * 写CSV文件,只写入一行 + * + */ + public static boolean csvFilePrinter(File file, String charset, String[] values) throws Exception{ + OutputStreamWriter fos = null; + try { + fos = new OutputStreamWriter( + new FileOutputStream(file), charset); + + + ExcelCSVPrinter ecsvp = new ExcelCSVPrinter(fos); + ecsvp.changeDelimiter(','); + ecsvp.setAutoFlush(true); + ecsvp.writeln(values); + + fos.flush(); + } catch (IOException e) { + throw e; + }finally { + if(fos!=null){ + try { + fos.close(); + } catch (IOException e) { + } + } + } + + return true; + } + + /** + * 写CSV文件,写入多行 + * + */ + public static boolean csvFilePrinter(File file, String charset, List values) throws Exception{ + OutputStreamWriter fos = null; + try { + fos = new OutputStreamWriter( + new FileOutputStream(file), charset); + + + ExcelCSVPrinter ecsvp = new ExcelCSVPrinter(fos); + ecsvp.changeDelimiter(','); + ecsvp.setAutoFlush(true); + for(String[] val : values){ + ecsvp.writeln(val); + } + + fos.flush(); + } catch (IOException e) { + throw e; + }finally { + if(fos!=null){ + try { + fos.close(); + } catch (IOException e) { + } + } + } + + return true; + } + + /** + * 解析CSV文件中的指定行 + * + */ + public static String[] csvFileParser(File file, String charset, int rowNum) throws Exception{ + Reader in = null; + String[] currLine = null; + try { + //创建解析信息流 + in = new InputStreamReader(new FileInputStream(file),charset); + + ExcelCSVParser csvParser = new ExcelCSVParser(in); + while((currLine=csvParser.getLine())!=null){ + if(rowNum != csvParser.getLastLineNumber()){ + currLine = null; + } + } + + } catch (IOException e) { + throw e; + }finally { + if(in!=null){ + try { + in.close(); + } catch (IOException e) { + } + } + } + + return currLine; + } + + /** + * 解析CSV文件的所有行 + * + */ + public static List csvFileParser(File file, String charset) throws Exception{ + Reader in = null; + List allLineList = new ArrayList(); + try { + //创建解析信息流 + in = new InputStreamReader(new FileInputStream(file),charset); + + ExcelCSVParser csvParser = new ExcelCSVParser(in); + String[] currLine = null; + while((currLine=csvParser.getLine())!=null){ + allLineList.add(currLine); + } + + } catch (IOException e) { + throw e; + }finally { + if(in!=null){ + try { + in.close(); + } catch (IOException e) { + } + } + } + + return allLineList; + } + +} diff --git a/src/com/nis/nmsclient/util/GzipUtil.java b/src/com/nis/nmsclient/util/GzipUtil.java new file mode 100644 index 0000000..75dce1b --- /dev/null +++ b/src/com/nis/nmsclient/util/GzipUtil.java @@ -0,0 +1,680 @@ +package com.nis.nmsclient.util; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +import org.apache.commons.io.IOUtils; +import org.apache.log4j.Logger; + +import com.ice.tar.TarEntry; +import com.ice.tar.TarInputStream; +import com.ice.tar.TarOutputStream; +import com.nis.nmsclient.common.Contants; + +/** + * gzip文件压缩与解压缩,对文件tar归档与解归档工具类 + * + */ +public class GzipUtil { + static Logger logger = Logger.getLogger(GzipUtil.class); + + /** + * 使用命令对单个gz压缩包解压 + * @param srcFileStr 需要解压的gz文件 + * @param destDir 解压后的目标路径 + * @param isAbs 解压文件时 true 按绝对路径解压, false 进入目标路径后解压 + * @throws Exception + */ + public static void unGzipByCmd(String srcFileStr, String destDir, boolean isAbs) throws Exception{ + logger.debug("unGzip start……"); + BufferedReader bReader = null; + BufferedReader errorReader = null; + Process process = null; + try { + logger.debug("unGzipByCmd srcFile---" + srcFileStr); + logger.debug("unGzipByCmd destDir---" + destDir); + + File srcFile = new File(srcFileStr); + File descFile = new File(destDir); + if(!srcFile.exists()){ + throw new Exception("source file not exist"); + } + if(!srcFile.isFile()){ + throw new Exception("source file is not a file"); + } + if(!descFile.exists()){ + descFile.mkdirs(); + } + if(!descFile.isDirectory()){ + throw new Exception("compress destination path is not a directory"); + } + String tarFile = srcFile.getParent() + File.separator + srcFile.getName().substring(0, srcFile.getName().length()-3); + StringBuffer sb = new StringBuffer(); + sb.append("gunzip " + srcFileStr); + sb.append(";tar xvpPf " + tarFile); + if(!isAbs){ + sb.append(" -C " + destDir); + }else{ + sb.append(" -C /"); + } + sb.append(";gzip " + tarFile); + logger.debug("unGzipByCmd cmd--->" + sb.toString()); + + String[] shellCmd = new String[] { "/bin/bash", "-c", sb.toString() }; + process = Runtime.getRuntime().exec(shellCmd); + process.getOutputStream().close(); + + bReader = new BufferedReader(new InputStreamReader(process + .getInputStream())); + errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); + String line = null; + while ((line = bReader.readLine()) != null) { + logger.debug("unGzipByCmd--->" + line); + } + while ((line = errorReader.readLine()) != null) { + logger.debug("unGzipByCmd error--->" + line); + throw new IOException(line); + } + + logger.debug("unGzipByCmd end……"); + } catch (Exception e) { + throw e; + } finally { + try { + if (bReader != null) { + bReader.close(); + } + if (errorReader != null) { + errorReader.close(); + } + if (process != null) { + process.destroy(); + } + } catch (Exception e) { + } + } + + } + + /** + * 使用命令将单个文件或一个目录压缩成Gzip格式 + * @param srcPath 需要压缩的文件目录或文件 + * @param destFileStr 压缩后的目标文件 + * @param excludes 排除的目录或文件(全是绝对路径),不包含到压缩包的 + * @param isAbs 压缩文件时 true 按绝对路径压缩(含有完成的路径压缩包), false 进入目标路径后压缩 + * @throws Exception + */ + public static void gzipByCmd(String srcPath, String destFileStr, String[] excludes, boolean isAbs) throws Exception{ + logger.debug("gzipByCmd start……"); + OutputStreamWriter fos = null; + BufferedReader bReader = null; + BufferedReader errorReader = null; + Process process = null; + File excludeFile = null; + boolean flag = true; + try { + logger.debug("gzipByCmd srcPath---" + srcPath); + logger.debug("gzipByCmd destFileStr---" + destFileStr); + + File srcFile = new File(srcPath); + File descFile = new File(destFileStr); + if(!srcFile.exists()){ + throw new Exception("decompress file not exist"); + } + if(!descFile.getParentFile().exists()){ + descFile.getParentFile().mkdirs(); + } + StringBuffer sb = new StringBuffer(); + if(!isAbs){ + if(srcFile.isFile()){ + sb.append("cd " + srcFile.getParentFile().getCanonicalPath() + ";"); + }else{ + sb.append("cd " + srcFile.getCanonicalPath() + ";"); + } + } + sb.append("tar -czvpPf " + destFileStr); + if(excludes!=null && excludes.length>0){ + if(!isAbs){ + for (int i = 0; i < excludes.length; i++) { + int index = excludes[i].indexOf(srcFile + .getCanonicalPath()); + logger.debug("gzipByCmd index--->" + index + "---src=" +srcFile + .getCanonicalPath()); + int start = index + srcFile.getCanonicalPath().length() + 1; + logger.debug("gzipByCmd start--->" + start + "--length=" + excludes[i].length() +"---exclude=" + excludes[i]); + if (index != -1 && start <= excludes[i].length()) { + excludes[i] = excludes[i].substring(start, + excludes[i].length()); + logger.debug("gzipByCmd exclude--->" + excludes[i]); + } + } + } + excludeFile = new File(Contants.localTempPath + File.separator + "excludelist_" + System.currentTimeMillis() + ".temp"); + // 2012-11-21 修改 由于使用FileWrUtil写的文件(有文件头的),Linux下无法正确识别 + fos = new OutputStreamWriter( + new FileOutputStream(excludeFile, true), System.getProperty("file.encoding")); + logger.debug("gzipByCmd ---- " + System.getProperty("file.encoding")); + for(String val : excludes){ + fos.write(val); + fos.write("\n"); + } + fos.flush(); + //FileWrUtil.cfgFilePrinter(excludeFile, Contants.charset, excludes); + sb.append(" -X " + excludeFile.getCanonicalPath()); + } + if(!isAbs){ + if(srcFile.isFile()){ + sb.append(" " + srcFile.getName()); + }else{ + sb.append(" *"); + } + }else{ + sb.append(" " + srcFile.getCanonicalPath()); + } + logger.debug("gzipByCmd cmd--->" + sb.toString()); + + String[] shellCmd = new String[] { "/bin/bash", "-c", sb.toString() }; + process = Runtime.getRuntime().exec(shellCmd); + process.getOutputStream().close(); + + bReader = new BufferedReader(new InputStreamReader(process + .getInputStream())); + errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); + String line = null; + while ((line = bReader.readLine()) != null) { + logger.debug("gzipByCmd--->" + line); + } + while ((line = errorReader.readLine()) != null) { + logger.debug("gzipByCmd error--->" + line); + flag = false; + throw new IOException(line); + } + + logger.debug("gzipByCmd end……"); + } catch (Exception e) { + throw e; + } finally { + try { + if(fos!=null){ + fos.close(); + } + if(excludeFile!=null && excludeFile.exists()){ + //excludeFile.delete_bak(); + //使用删除文件公共方法 + FileUtil.delDir(excludeFile); + logger.debug("GzipUtil.gzipByCmd()--delete excludeFile=" + excludeFile.getAbsolutePath()); + //FileUtil.checkParentDirExist(excludeFile); + } + if (bReader != null) { + bReader.close(); + } + if (errorReader != null) { + errorReader.close(); + } + if (process != null) { + process.destroy(); + } + if(!flag){ + File destFile = new File(destFileStr); + if(destFile.exists()){ + //destFile.delete_bak(); + //使用删除文件公共方法 + FileUtil.delDir(destFile); + logger.debug("GzipUtil.gzipByCmd()--delete destFile=" + destFile.getAbsolutePath()); + //FileUtil.checkParentDirExist(destFile); + } + } + } catch (Exception e) { + } + } + + } + + /** + * 使用命令对单个tar压缩包解压 + * @param srcFileStr 需要解压的gz文件 + * @param destDir 解压后的目标路径 + * @param isAbs 解压文件时 true 按绝对路径解压, false 进入目标路径后解压 + * @throws Exception + */ + public static void unTarByCmd(String srcFileStr, String destDir, boolean isAbs) throws Exception{ + logger.debug("unTarByCmd start……"); + BufferedReader bReader = null; + BufferedReader errorReader = null; + Process process = null; + try { + logger.debug("unTarByCmd srcFile---" + srcFileStr); + logger.debug("unTarByCmd destDir---" + destDir); + + File srcFile = new File(srcFileStr); + File descFile = new File(destDir); + if(!srcFile.exists()){ + throw new Exception("source file not exist"); + } + if(!srcFile.isFile()){ + throw new Exception("source file is not a file"); + } + if(!descFile.exists()){ + descFile.mkdirs(); + } + if(!descFile.isDirectory()){ + throw new Exception("compress destination path is not a directory"); + } + StringBuffer sb = new StringBuffer(); + sb.append("tar xvpPf " + srcFileStr); + if(!isAbs){ + sb.append(" -C " + destDir); + }else{ + sb.append(" -C /"); + } + logger.debug("unTarByCmd cmd--->" + sb.toString()); + + String[] shellCmd = new String[] { "/bin/bash", "-c", sb.toString() }; + process = Runtime.getRuntime().exec(shellCmd); + process.getOutputStream().close(); + + bReader = new BufferedReader(new InputStreamReader(process + .getInputStream())); + errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); + String line = null; + while ((line = bReader.readLine()) != null) { + logger.debug("unTarByCmd--->" + line); + } + while ((line = errorReader.readLine()) != null) { + logger.debug("unTarByCmd--->" + line); + throw new IOException(line); + } + + logger.debug("unTarByCmd end……"); + } catch (Exception e) { + throw e; + } finally { + try { + if (bReader != null) { + bReader.close(); + } + if (errorReader != null) { + errorReader.close(); + } + if (process != null) { + process.destroy(); + } + } catch (Exception e) { + } + } + + } + + /** + * 使用命令将单个文件或一个目录压缩成tar格式 + * @param srcPath 需要压缩的文件目录或文件 + * @param destFileStr 压缩后的目标文件 + * @param excludes 排除的目录或文件(全是绝对路径),不包含到压缩包的 + * @param isAbs 压缩文件时 true 按绝对路径压缩(含有完成的路径压缩包), false 进入目标路径后压缩 + * @throws Exception + */ + public static void tarByCmd(String srcPath, String destFileStr, String[] excludes, boolean isAbs) throws Exception{ + logger.debug("tarByCmd start……"); + BufferedReader bReader = null; + BufferedReader errorReader = null; + Process process = null; + File excludeFile = null; + boolean flag = true; + try { + logger.debug("tarByCmd srcPath---" + srcPath); + logger.debug("tarByCmd destFileStr---" + destFileStr); + + File srcFile = new File(srcPath); + File descFile = new File(destFileStr); + if(!srcFile.exists()){ + throw new Exception("decompress file not exist"); + } + if(!descFile.getParentFile().exists()){ + descFile.getParentFile().mkdirs(); + } + StringBuffer sb = new StringBuffer(); + if(!isAbs){ + if(srcFile.isFile()){ + sb.append("cd " + srcFile.getParentFile().getCanonicalPath() + ";"); + }else{ + sb.append("cd " + srcFile.getCanonicalPath() + ";"); + } + } + sb.append("tar -cvpPf " + destFileStr); + if(excludes!=null && excludes.length>0){ + if(!isAbs){ + for (int i = 0; i < excludes.length; i++) { + int index = excludes[i].indexOf(srcFile + .getCanonicalPath()); + logger.debug("tarByCmd index--->" + index + "---src=" +srcFile + .getCanonicalPath()); + int start = index + srcFile.getCanonicalPath().length() + 1; + logger.debug("tarByCmd start--->" + start + "--length=" + excludes[i].length() +"---exclude=" + excludes[i]); + if (index != -1 && start <= excludes[i].length()) { + excludes[i] = excludes[i].substring(start, + excludes[i].length()); + logger.debug("tarByCmd exclude--->" + excludes[i]); + } + } + } + excludeFile = new File(Contants.localTempPath + File.separator + "excludelist_" + System.currentTimeMillis() + ".temp"); + FileWrUtil.cfgFilePrinter(excludeFile, Contants.charset, excludes); + sb.append(" -X " + excludeFile.getCanonicalPath()); + } + if(!isAbs){ + if(srcFile.isFile()){ + sb.append(" " + srcFile.getName()); + }else{ + sb.append(" *"); + } + }else{ + sb.append(" " + srcFile.getCanonicalPath()); + } + logger.debug("tarByCmd cmd--->" + sb.toString()); + + String[] shellCmd = new String[] { "/bin/bash", "-c", sb.toString() }; + process = Runtime.getRuntime().exec(shellCmd); + process.getOutputStream().close(); + + bReader = new BufferedReader(new InputStreamReader(process + .getInputStream())); + errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); + String line = null; + while ((line = bReader.readLine()) != null) { + logger.debug("tarByCmd--->" + line); + } + while ((line = errorReader.readLine()) != null) { + logger.debug("tarByCmd error--->" + line); + flag = false; + throw new IOException(line); + } + + logger.debug("tarByCmd end……"); + } catch (Exception e) { + throw e; + } finally { + try { + if(excludeFile!=null && excludeFile.exists()){ + //excludeFile.delete_bak(); + //使用删除文件公共方法 + FileUtil.delDir(excludeFile); + logger.debug("GzipUtil.tarByCmd()--delete excludeFile=" + excludeFile.getAbsolutePath()); + //FileUtil.checkParentDirExist(excludeFile); + } + if (bReader != null) { + bReader.close(); + } + if (errorReader != null) { + errorReader.close(); + } + if (process != null) { + process.destroy(); + } + if(!flag){ + File destFile = new File(destFileStr); + if(destFile.exists()){ + //destFile.delete_bak(); + //使用删除文件公共方法 + FileUtil.delDir(destFile); + logger.debug("GzipUtil.tarByCmd()--delete destFile=" + destFile.getAbsolutePath()); + //FileUtil.checkParentDirExist(destFile); + } + } + } catch (Exception e) { + } + } + } + + /** + * 对单个gz压缩包解压 + * @param srcFile 需要解压的gz文件 + * @param destDir 解压后的目标路径 + * @throws Exception + */ + public static void unGzip(String srcFile, String destDir) throws Exception{ + logger.debug("unGzip start……"); + OutputStream out = null; + GZIPInputStream gis = null; + File tempFile = new File(destDir + File.separator + System.currentTimeMillis() + ".tar"); + try { + logger.debug("unGzip tempFile----" + tempFile.getAbsolutePath()); + logger.debug("unGzip srcFile---" + srcFile); + logger.debug("unGzip destDir---" + destDir); + gis = new GZIPInputStream(new FileInputStream(new File(srcFile))); + + if(!tempFile.getParentFile().exists()){ + tempFile.getParentFile().mkdirs(); + } + out = new FileOutputStream(tempFile); + logger.debug("unGzip tempFile---------" + tempFile.getAbsolutePath()); + byte[] buf = new byte[1024 * 2]; + int len = 0; + while ((len = gis.read(buf)) != -1) { + logger.debug("unGzip len---------" + len); + out.write(buf, 0, len); + } + out.flush(); + + //tar包解归档 + GzipUtil.unTar(tempFile.getAbsolutePath(), destDir); + + logger.debug("unGzip end……"); + } catch (Exception e) { + throw e; + } finally { + try { + if(gis!=null) gis.close(); + if(out!=null) out.close(); + } catch (Exception e) { + e.printStackTrace(); + } + logger.debug("tempFile.delete() start……" + tempFile.getAbsolutePath()); + if(tempFile.exists()){ + //tempFile.delete_bak(); + //使用删除文件公共方法 + FileUtil.delDir(tempFile); + logger.debug("unGzip delete file --" + tempFile.getAbsolutePath()); + //FileUtil.checkParentDirExist(tempFile); + } + logger.debug("tempFile.delete() end……" + tempFile.getAbsolutePath()); + } + + } + + /** + * 将单个文件或一个目录压缩成Gzip格式 + * + * @param srcPath 需要压缩的文件目录或文件 + * @param destFile 压缩后的目标文件 + * @throws Exception + */ + public static void gzip(String srcPath, String destFile) throws Exception { + File tempFile = new File(new File(destFile).getParent() + File.separator + System.currentTimeMillis() + ".tar"); + GZIPOutputStream gzout = null; + FileInputStream tarin = null; + try{ + //tar包归档 + GzipUtil.tar(srcPath, tempFile.getAbsolutePath()); + + //建立gzip压缩输出流 + gzout = new GZIPOutputStream(new FileOutputStream(destFile)); + //打开需压缩文件作为文件输入流 + tarin = new FileInputStream(tempFile); + int len; + byte[] buf = new byte[1024 * 2]; + while ((len = tarin.read(buf)) != -1) { + gzout.write(buf, 0, len); + } + gzout.flush(); + + }catch (Exception e) { + throw e; + }finally { + if(tarin!=null) tarin.close(); + if(gzout!=null) gzout.close(); + if(tempFile.exists()){ + //tempFile.delete_bak(); + //使用删除文件公共方法 + FileUtil.delDir(tempFile); + logger.debug("GzipUtil.gzip()--delete tempFile=" + tempFile.getAbsolutePath()); + //FileUtil.checkParentDirExist(tempFile); + } + } + } + + + /** + * 对单个tar压缩包解压,即解归档 + * + * @param srcFile 需要解压的tar文件 + * @param outpath 解压后的目标路径 + * @throws Exception + */ + public static void unTar(String srcFile, String outpath) throws Exception{ + logger.debug("unTar start……"); + TarInputStream tis = null; + try { + logger.debug("unTar srcFile---" + srcFile); + logger.debug("unTar outpath---" + outpath); + File file = new File(srcFile); + if(!file.exists()){ +// throw new Exception("解压源文件不存在: " + file.getAbsolutePath()); + throw new Exception("Unzip source file does not exist: " + file.getAbsolutePath()); + } + tis = new TarInputStream(new FileInputStream(file)); + /*关键在于这个TarEntry 的理解, 实际你的tar包里有多少文件就有多少TarEntry*/ + TarEntry tarEntry = null; + while ((tarEntry = tis.getNextEntry()) != null) { + logger.debug("unTar tarEntry---" + tarEntry); + String tempFileName = (outpath + File.separator + tarEntry.getName()).replaceAll("\\\\", "/"); + logger.debug("unTar tempFileName---" + tempFileName); + if (tarEntry.isDirectory()) { + logger.debug("unTar tarEntry is Dir"); + int end = tempFileName.lastIndexOf("/"); + if (end != -1) { + File dir = new File(tempFileName.substring(0, end)); + if (!dir.exists()) { + dir.mkdirs(); + } + } + } else { + logger.debug("unTar tarEntry is file"); + File tempFile = new File(tempFileName); + if(!tempFile.getParentFile().exists()){ + tempFile.getParentFile().mkdirs(); + } + tempFile.createNewFile(); + OutputStream out = new FileOutputStream(tempFile); + IOUtils.copy(tis, out); + out.close(); + } + } + logger.debug("unTar end……"); + } catch (Exception e) { + throw e; + } finally { + try { + if(tis!=null) tis.close(); + } catch (Exception e) { + e.printStackTrace(); + } + + } + + } + + /** + * 将单个文件或一个目录打成tar包,即归档 + * + * @param srcDir 需要压缩的文件目录或文件 + * @param destFile 压缩后的目标文件 + * @throws Exception + */ + public static void tar(String srcDir, String destFile) throws Exception { + TarOutputStream tout = null; + try{ + //建立tar压缩输出流 + tout = new TarOutputStream(new FileOutputStream(destFile)); + File srcFile = new File(srcDir); + if (!srcFile.exists()) { +// throw new Exception("压缩目录或文件不存在: " + srcFile.getAbsolutePath()); + throw new Exception("Compressed directories or files do not exist: " + srcFile.getAbsolutePath()); + } + if(srcFile.isDirectory()){ + tar(tout,srcFile,srcFile.getName()); + }else{ + tar(tout,srcFile,""); + } + }catch (Exception e) { + throw e; + }finally { + if(tout!=null) tout.close(); + } + } + + /** + * tar压缩 + * @param out: tar压缩流 + * @param srcFile: 需要压缩的目录或文件 + * @param base: 需要压缩的文件在压缩后的tar包内的路径 + * @throws Exception + */ + public static void tar(TarOutputStream tout, File srcFile, String base) throws Exception{ + if (!srcFile.exists()) { +// throw new Exception("压缩目录或文件不存在: " + srcFile.getAbsolutePath()); + throw new Exception("Compressed directories or files do not exist: " + srcFile.getAbsolutePath()); + } + if (srcFile.isDirectory()) { + File[] files = srcFile.listFiles(); + base = base.length() == 0 ? "" : base + "/"; + if (base.length() > 0) { + TarEntry tarEn = new TarEntry(srcFile); //此处必须使用new TarEntry(File file); + tarEn.setName(base); //此处需重置名称,默认是带全路径的,否则打包后会带全路径 + tout.putNextEntry(tarEn); + } + for (int i = 0; i < files.length; i++) { + tar(tout, files[i], base + files[i].getName()); + } + } else { + base = base.length() == 0 ? srcFile.getName() : base; + TarEntry tarEn = new TarEntry(srcFile); + tarEn.setName(base); + tout.putNextEntry(tarEn); + FileInputStream fis = null; + try{ + fis = new FileInputStream(srcFile); + IOUtils.copy(fis, tout); + }catch (IOException e) { + throw e; + }finally{ + if(fis!=null) fis.close(); + } + } + tout.closeEntry(); + } + + + public static void main(String[] args) { + try { + long tt = System.currentTimeMillis(); + //tar("D:\\temp\\test", "d:\\temp\\t1.tar"); + //unTar("D:\\temp\\t1.tar", "D:\temp\\t1"); + + //gzip("D:\\temp\\t1\\gd-2.0.350000", "d:\\temp\\test\\t1.tar.gz"); + unGzip("d:\\temp\\nms.tar.gz", "D:\\temp\\t1"); + System.out.println(System.currentTimeMillis()-tt); + } catch (Exception e) { + e.printStackTrace(); + } + } + +} + diff --git a/src/com/nis/nmsclient/util/MD5Util.java b/src/com/nis/nmsclient/util/MD5Util.java new file mode 100644 index 0000000..7d2ac4f --- /dev/null +++ b/src/com/nis/nmsclient/util/MD5Util.java @@ -0,0 +1,99 @@ +package com.nis.nmsclient.util; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +public class MD5Util { + /** + * 默认的密码字符串组合,apache校验下载的文件的正确性用的就是默认的这个组合 + */ + protected static char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', + '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + protected static MessageDigest messagedigest = null; + static { + try { + messagedigest = MessageDigest.getInstance("MD5"); + } catch (NoSuchAlgorithmException nsaex) { + System.err.println(MD5Util.class.getName() + + "初始化失败,MessageDigest不支持MD5Util。"); + nsaex.printStackTrace(); + } + } + + public static void main(String[] args) throws IOException { + long begin = System.currentTimeMillis(); + + // 2EA3E66AC37DF7610F5BD322EC4FFE48 670M 11s kuri双核1.66G 2G内存 + File big = new File("I:/大型安装程序的压缩版本/Rational rose 2003.rar"); + + String md5 = getFileMD5String(big); + + long end = System.currentTimeMillis(); + System.out.println("md5:" + md5 + " time:" + ((end - begin) / 1000) + + "s"); + } + + /** + * 适用于上G大的文件 + * + * @param file + * @return + * @throws IOException + */ + public static String getFileMD5String(File file) throws IOException { + FileInputStream in = null; + try { + in = new FileInputStream(file); + FileChannel ch = in.getChannel(); + MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, 0, + file.length()); + messagedigest.update(byteBuffer); + return bufferToHex(messagedigest.digest()); + } catch (Exception e) { + throw new IOException(e.getCause()); + }finally{ + if(in!=null){ + in.close(); + } + } + } + + public static String getMD5String(String s) { + return getMD5String(s.getBytes()); + } + + public static String getMD5String(byte[] bytes) { + messagedigest.update(bytes); + return bufferToHex(messagedigest.digest()); + } + + private static String bufferToHex(byte bytes[]) { + return bufferToHex(bytes, 0, bytes.length); + } + + private static String bufferToHex(byte bytes[], int m, int n) { + StringBuffer stringbuffer = new StringBuffer(2 * n); + int k = m + n; + for (int l = m; l < k; l++) { + appendHexPair(bytes[l], stringbuffer); + } + return stringbuffer.toString(); + } + + private static void appendHexPair(byte bt, StringBuffer stringbuffer) { + char c0 = hexDigits[(bt & 0xf0) >> 4]; + char c1 = hexDigits[bt & 0xf]; + stringbuffer.append(c0); + stringbuffer.append(c1); + } + + public static boolean checkPassword(String password, String md5PwdStr) { + String s = getMD5String(password); + return s.equals(md5PwdStr); + } +} diff --git a/src/com/nis/nmsclient/util/ProcessUtil.java b/src/com/nis/nmsclient/util/ProcessUtil.java new file mode 100644 index 0000000..461a8d1 --- /dev/null +++ b/src/com/nis/nmsclient/util/ProcessUtil.java @@ -0,0 +1,1341 @@ +package com.nis.nmsclient.util; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import org.apache.log4j.Logger; +import com.nis.nmsclient.common.Contants; + +public class ProcessUtil +{ + + static Logger logger = Logger.getLogger(ProcessUtil.class); + private static final String EXEC_CMD_FILE = Contants.LOCAL_SCRIPT_PATH + "/execCmdBySu.sh"; + private static final String CHECK_USERPASS_FILE = Contants.LOCAL_SCRIPT_PATH + + "/check_userpass.sh"; + private static Byte[] oWin = new Byte[0]; + private static Byte[] oLinux = new Byte[0]; + + /** + * 从文件读取PID值 + * + * @param pidFile + * 存放PID的文件 + * @return PID数组 + * @throws Exception + */ + public static String[] getProcessIdByFile(File pidFile) throws Exception + { + String[] pids = null; + if (pidFile.exists()) + { + String[] values = FileWrUtil.cfgFileReader(pidFile); + if (values != null && values.length > 0 && values[0].trim().length() > 0) + { + pids = values[0].trim().split(","); + } + + } + return pids; + } + + /** + * 根据PID按不同操作系统判断进程是否存在 + * + * @param pid + * @return true 存在,false 不存在 + * @throws Exception + */ + public static boolean isProcessExistByPid(String pid) throws Exception + { + boolean flag = false; + // 根据操作系统确定获取进程ID的方式 + String os = System.getProperty("os.name"); + if (os.startsWith("Windows")) + { + flag = isWinProcessExistByPid(pid.trim()); + } else if (os.startsWith("Linux")) + { + flag = isLinuxProcessExistByPid(pid.trim()); + } else + { + throw new IOException("unknown operating system: " + os); + } + + return flag; + } + + /** + * 根据PID判断Linux下进程是否存在 + * + * @param pid + * @return + */ + public static boolean isLinuxProcessExistByPid(String pid) + { + String cmd = "ps -p " + pid.trim() + " | grep " + pid.trim() + + " | grep -v defunct | awk '{print $1}'"; + String[] shellCmd1 = new String[] { "/bin/bash", "-c", cmd }; + BufferedReader bReader = null; + BufferedReader errorReader = null; + Process process = null; + boolean flag = false; + logger.info("isLinuxProcessExistByPid cmd-----" + cmd); + synchronized (oLinux) + { + try + { + // 找到根据进程名获取到的进程号列表 + process = Runtime.getRuntime().exec(shellCmd1); + process.getOutputStream().close(); + + bReader = new BufferedReader(new InputStreamReader(process.getInputStream())); + errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); + String line = null; + while ((line = bReader.readLine()) != null) + { + logger.debug("isLinuxProcessExistByPid line-----" + line); + flag = true; + } + while ((line = errorReader.readLine()) != null) + { + logger.debug("isLinuxProcessExistByPid error line--->" + line); + } + + } catch (IOException e) + { + logger.error(Utils.printExceptionStack(e)); + } finally + { + try + { + if (bReader != null) + { + bReader.close(); + } + if (errorReader != null) + { + errorReader.close(); + } + if (process != null) + { + process.destroy(); + } + } catch (IOException e) + { + logger.error(Utils.printExceptionStack(e)); + } + } + + } + return flag; + } + + /** + * 根据PID判断Windows下进程是否存在 + * + * @param pid + * @return + */ + public static boolean isWinProcessExistByPid(String pid) + { + String[] cmd = new String[] { "cmd.exe", "/C", + "wmic process where processId=" + pid.trim() + " get processId" }; + logger.info("isWinProcessExistByPid cmd-----" + cmd[2]); + BufferedReader bReader = null; + BufferedReader errorReader = null; + Process process = null; + boolean flag = false; + try + { + synchronized (oWin) + { + process = Runtime.getRuntime().exec(cmd); + process.getOutputStream().close(); + bReader = new BufferedReader(new InputStreamReader(process.getInputStream())); + errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); + String line = null; + while ((line = bReader.readLine()) != null) + { + logger.debug("isWinProcessExistByPid line-----" + line); + if (line.trim().equals(pid.trim())) + { + flag = true; + } + } + while ((line = errorReader.readLine()) != null) + { + logger.debug("isWinProcessExistByPid error line--->" + line); + } + } + + } catch (IOException e) + { + logger.error(Utils.printExceptionStack(e)); + } finally + { + try + { + if (bReader != null) + { + bReader.close(); + } + if (errorReader != null) + { + errorReader.close(); + } + if (process != null) + { + process.destroy(); + } + } catch (IOException e) + { + logger.error(Utils.printExceptionStack(e)); + } + } + + return flag; + } + + /** + * Linux下执行命令 + * + * @param cmd + * @return + * @throws Exception + */ + public static String execLinuxCmd(String cmd) throws Exception + { + BufferedReader bReader = null; + BufferedReader errorReader = null; + Process process = null; + try + { + // logger.debug("execLinuxCmd start-------" + cmd); + String[] shellCmd = new String[] { "/bin/bash", "-c", cmd }; + process = Runtime.getRuntime().exec(shellCmd); + process.getOutputStream().close(); + + bReader = new BufferedReader(new InputStreamReader(process.getInputStream())); + errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); + String line = null; + while ((line = bReader.readLine()) != null) + { + logger.debug("execLinuxCmd line--->" + line); + } + StringBuffer errorSb = new StringBuffer(); + while ((line = errorReader.readLine()) != null) + { + logger.debug("execLinuxCmd error line--->" + line); + errorSb.append(line + ","); + } + + if (errorSb.toString().length() > 0) + { + errorSb.deleteCharAt(errorSb.length() - 1); + return errorSb.toString(); + } + + // logger.debug("execLinuxCmd end-------" + cmd); + } catch (Exception e) + { + throw e; + } finally + { + try + { + if (bReader != null) + { + bReader.close(); + } + if (errorReader != null) + { + errorReader.close(); + } + if (process != null) + { + process.destroy(); + } + } catch (Exception e1) + { + } + } + return null; + } + + /** + * windows下执行命令 + * + * @param cmd + * @return + * @throws Exception + */ + public static String execWinCmd(String cmd) throws Exception + { + BufferedReader bReader = null; + BufferedReader errorReader = null; + Process process = null; + try + { + logger.debug("execWinCmd start-------" + cmd); + //cmd = handlerWinSpace(cmd); + String[] cmdArr = new String[] { "cmd.exe", "/C", cmd }; + process = Runtime.getRuntime().exec(cmdArr); + if (cmd.endsWith(".exe")) + { + synchronized (process) + { + process.wait(1000 * 5); + } + process.getOutputStream().close(); + process.getInputStream().close(); + process.getErrorStream().close(); + } else + { + process.getOutputStream().close(); + Charset platform = Charset.forName(System.getProperty("sun.jnu.encoding")); + bReader = new BufferedReader(new InputStreamReader(process.getInputStream(), platform)); + errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), platform)); + String line = null; + while ((line = bReader.readLine()) != null) + { + logger.debug("execWinCmd line--->" + line); + } + StringBuffer errorSb = new StringBuffer(); + while ((line = errorReader.readLine()) != null) + { + logger.debug("execWinCmd error--->" + line); + errorSb.append(line + ","); + } + if (errorSb.length() > 0) + { + errorSb.deleteCharAt(errorSb.length() - 1); + return errorSb.toString(); + } + } + + logger.debug("execWinCmd end-------" + cmd); + + } catch (Exception e) + { + throw e; + } finally + { + try + { + if (bReader != null) + { + bReader.close(); + } + if (errorReader != null) + { + errorReader.close(); + } + if (process != null) + { + process.destroy(); + } + } catch (Exception e1) + { + } + } + + return null; + } + + /** + * 执行文件或命令,不同的操作系统按相应方式执行 + * + * @param cmd + * 文件全路径或执行命令 + * @param cmdParams + * 执行参数 + * @param username + * 执行用户 + * @param passwd + * 执行用户的密码 + * @return 返回错误输出:若有返回,则执行失败;若返回null,则执行成功 + * @throws IOException + */ + public static String runExec(String cmd, String[] cmdParams, String username, String passwd) + throws IOException + { + return runExec(cmd, cmdParams, username, passwd, false); + } + + /** + * 执行文件或命令,不同的操作系统按相应方式执行 + * + * @param isDaemon + * 若为true, NC守护进程, 不读取输出;若为false, 执行文件或命令,读取输出 + * @return + * @throws IOException + */ + public static String runExec(String cmd, String[] cmdParams, String username, String passwd, + boolean isDaemon) throws IOException + { + // 根据操作系统确定运行方式 + String os = System.getProperty("os.name"); + Process process = null; + try + { + logger.debug("runExec start-------" + cmd); + String error = null; + if (os.startsWith("Windows")) + { + StringBuffer sb = new StringBuffer(); + if (isDaemon) + {// -- 执行NC守护进程脚本 + sb.append("start /b " + handlerWinSpace(cmd)); + if (cmdParams != null && cmdParams.length > 0) + { + // 如果执行参数为数组类型时使用 + for (String param: cmdParams) + { + // 带空格参数的特殊处理 + sb.append(" " + handlerWinSpace(param)); + } + } + sb.append(" >nul 2>&1"); + logger.info("runExec Windows-------" + sb.toString()); + String[] cmdArr = new String[] { "cmd.exe", "/C", sb.toString() }; + process = Runtime.getRuntime().exec(cmdArr); + synchronized (process) + { + process.wait(1000 * 5); + } + process.getOutputStream().close(); + process.getInputStream().close(); + process.getErrorStream().close(); + } else + { + sb.append(handlerWinSpace(cmd)); + if (cmdParams != null && cmdParams.length > 0) + { + // 如果执行参数为数组类型时使用 + for (String param: cmdParams) + { + // 带空格参数的特殊处理 + sb.append(" " + handlerWinSpace(param)); + } + } + logger.info("runExec Windows-------" + sb.toString()); + error = execWinCmd(sb.toString()); + } + } else if (os.startsWith("Linux")) + { + StringBuffer sb = new StringBuffer(); + sb.append("nohup " + cmd.trim()); + if (cmdParams != null && cmdParams.length > 0) + { + // 如果执行参数为数组类型时使用 + for (String param: cmdParams) + { + // 带空格参数的特殊处理 + sb.append(" " + handlerLinuxSpace(param)); + } + } + sb.append(" >/dev/null 2>&1 &"); + logger.info("runExec Linux-------" + sb.toString()); + if (username != null && username.trim().length() > 0) + { + // -- 有密码调用execCmdBySu.sh文件执行 + if (passwd != null && passwd.trim().length() > 0) + { + File file = new File(EXEC_CMD_FILE); + // 执行结果标识参数1、0 表示执行命令后是否添加:echo $? + String temp = file.getCanonicalPath() + " 1 \"" + sb.toString() + "\" " + + username.trim(); + logger.info("runExec-->" + temp); + temp += " " + DESUtil.desDecrypt(passwd.trim()); + sb.delete(0, sb.length()); + sb.append("nohup " + temp + " >/dev/null 2>&1 &"); + } else + { + // -- 无密码自己拼命令 + String temp = "su - -c \"" + sb.toString() + "\" " + username.trim(); + logger.info("runExec-->" + temp); + sb.delete(0, sb.length()); + sb.append(temp); + } + } + error = execLinuxCmd(sb.toString()); + } else + { + throw new IOException("unknown operating system: " + os); + } + + logger.debug("sleep: 10 seconds"); + Thread.sleep(10 * 1000); + + logger.debug("runExec end-------" + cmd); + + return error; + } catch (Exception e) + { + logger.error(Utils.printExceptionStack(e)); +// return "出现异常:" + e.getMessage(); + return "Abnormality:" + e.getMessage(); + } finally + { + try + { + if (process != null) + { + process.destroy(); + } + } catch (Exception e1) + { + } + } + + } + + /** + * 赋权限:若path是目录,给目录下所有文件赋指定的权限 + * + * @param permit + * 权限的整数值 + * @param path + * 需要赋权限的文件或目录 + */ + public static void permit(long permit, File path) + { + // 根据操作系统确定运行方式 + String os = System.getProperty("os.name"); + logger.debug("permit-----path=" + path.getAbsolutePath()); + try + { + if (os.startsWith("Linux") && path != null && path.exists()) + { + if (path.isDirectory() && path.listFiles().length > 0) + { + execLinuxCmd("chmod " + permit + " " + + handlerLinuxSpace(path.getCanonicalPath()) + File.separator + "*"); + File[] files = path.listFiles(); + for (File file: files) + { + if (file.isDirectory()) + { + permit(permit, file); + } + } + } else + { + execLinuxCmd("chmod " + permit + " " + + handlerLinuxSpace(path.getCanonicalPath())); + } + } + } catch (Exception e) + { + logger.error(Utils.printExceptionStack(e)); + } + } + + /** + * 杀进程:根据操作系统以不同的方式停用进程 + * + * @param processId + * @throws IOException + */ + public static void killProcess(String processId) throws IOException + { + // 根据操作系统确定运行方式 + String os = System.getProperty("os.name"); + try + { + if (os.startsWith("Windows")) + { + String cmd = "wmic process where processId=" + processId + " delete"; + logger.debug("killProcess win cmd-------" + cmd); + execWinCmd(cmd); + } else if (os.startsWith("Linux")) + { + String cmd = "kill -9 " + processId; + logger.debug("killProcess linux cmd-------" + cmd); + execLinuxCmd(cmd); + } else + { + throw new IOException("unknown operating system: " + os); + } + Thread.sleep(5 * 1000); + } catch (Exception e) + { + logger.error(Utils.printExceptionStack(e)); + } + } + + /** + * 只能用来运行命令,取得运行命令的输出结果,根据错误输出流来判断命令运行成功与否 如果需切换用户,调用execCmdBySu.sh执行 + * + * @param cmd + * @param username + * @return 成功:0|命令输出信息;失败:1|失败信息 + * @throws Exception + */ + public static String runExecGetResult(String cmd, String username, String passwd) + throws Exception + { + BufferedReader bReader = null; + BufferedReader errorReader = null; + Process process = null; + String seprator = "|"; + try + { + logger.debug("runExecGetResult start-------" + cmd); + String os = System.getProperty("os.name");// 根据操作系统确定运行方式 + String result = "0" + seprator; + String[] cmdArr = null; + if (os.startsWith("Windows")) + { + // 【&& echo 0 || echo 1】 执行成功输出0,执行失败输出1,为了与Linux下的一致来取执行结果 + String tempCmd = handlerWinSpace(cmd) + " && echo 0 || echo 1"; + logger.info("runExecGetResult-->" + tempCmd); + cmdArr = new String[] { "cmd.exe", "/C", tempCmd }; + } else if (os.startsWith("Linux")) + { + String tempCmd = cmd.trim(); + if (username != null && username.trim().length() > 0) + { + // -- 有密码调用execCmdBySu.sh文件执行 + if (passwd != null && passwd.trim().length() > 0) + { + File file = new File(EXEC_CMD_FILE); + // 执行结果标识参数1、0 表示执行命令后是否添加:echo $? + tempCmd = file.getCanonicalPath() + " 0 \"" + cmd.trim() + "\" " + + username.trim(); + logger.info("runExecGetResult-->" + tempCmd); + tempCmd += " " + DESUtil.desDecrypt(passwd.trim()); + } else + { + // -- 无密码自己拼命令 + tempCmd = "su - -c \"" + cmd.trim() + ";echo $?\" " + username.trim(); + logger.info("runExecGetResult-->" + tempCmd); + } + } else + { + tempCmd += ";echo $?";// 为了与脚本中的echo $?运行命令保持一致 + logger.info("runExecGetResult-->" + tempCmd); + } + cmdArr = new String[] { "/bin/bash", "-c", tempCmd }; + } else + { + throw new IOException("unknown operating system: " + os); + } + process = Runtime.getRuntime().exec(cmdArr); + process.getOutputStream().close(); + bReader = new BufferedReader(new InputStreamReader(process.getInputStream())); + errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); + String line = null; + StringBuffer sb = new StringBuffer(); + while ((line = bReader.readLine()) != null) + { + sb.append(line + ","); + logger.debug("runExecGetResult right-->" + line); + } + StringBuffer errorSb = new StringBuffer(); + while ((line = errorReader.readLine()) != null) + { + errorSb.append(line + ","); + logger.debug("runExecGetResult error-->" + line); + } + if (errorSb.length() > 0) + { + errorSb.deleteCharAt(errorSb.length() - 1); + result = "1" + seprator + errorSb.toString(); + } else if (sb.length() > 0) + { + sb.deleteCharAt(sb.length() - 1);// 去掉最后一个逗号 + int lastIndex = sb.lastIndexOf(","); + String flag = ""; + logger.debug("runExecGetResult lastIndex-->" + lastIndex); + if (lastIndex != -1) + { + // 配合运行命令(echo $?),最后一行为结果标识 + flag = sb.substring(lastIndex + 1, sb.length()).trim(); + sb.delete(lastIndex, sb.length());// 删除结果标识和其前面的逗号 + } else + { + flag = sb.toString().trim(); + sb.delete(0, sb.length()); + } + logger.debug("runExecGetResult flag-->" + flag); + // 配合运行命令(echo $?):最后一行若是0,则执行成功,若非0,则失败 + if ("0".equals(flag)) + { + result = "0" + seprator + sb.toString(); + } else + { + result = "1" + seprator + sb.toString(); + } + } + logger.debug("runExecGetResult result-->" + result); + logger.debug("runExecGetResult end-------" + cmd); + + return result; + } catch (Exception e) + { + throw e; + } finally + { + try + { + if (bReader != null) + { + bReader.close(); + } + if (errorReader != null) + { + errorReader.close(); + } + if (process != null) + { + process.destroy(); + } + } catch (Exception e1) + { + } + } + } + + /** + * 验证用户名或用户组是否存在 + * + * @param username + * @param userGroup + * @return + * @throws Exception + */ + public static boolean checkUserOrGroupExist(String username, String userGroup) throws Exception + { + try + { + boolean flag = false; + logger.debug("checkUserOrGroupExist start-------"); + String os = System.getProperty("os.name");// 根据操作系统确定运行方式 + if (os.startsWith("Windows")) + { + flag = true; + } else if (os.startsWith("Linux")) + { + if (username == null && userGroup == null) + { + flag = true; + } else + { + StringBuffer sb = new StringBuffer(); + if (username != null) + { + sb.append("su " + username.trim() + ";"); + } + if (userGroup != null) + { + sb.append("groups " + userGroup.trim() + ";"); + } + if (execLinuxCmd(sb.toString()) == null) + {// 没有返回值,验证通过 + flag = true; + } + } + } else + { + throw new IOException("unknown operating system: " + os); + } + + logger.debug("checkUserOrGroupExist end-------"); + + return flag; + } catch (Exception e) + { + throw e; + } + + } + + /** + * 验证用户名和密码是否正确,调用check_userpass.sh脚本 + * + * @param username + * @param passwd + */ + public static boolean checkUserPass(String username, String passwd) throws Exception + { + BufferedReader bReader = null; + BufferedReader errorReader = null; + Process process = null; + try + { + boolean flag = false; + logger.debug("checkUserPass start-------"); + String os = System.getProperty("os.name");// 根据操作系统确定运行方式 + if (os.startsWith("Windows")) + { + flag = true; + } else if (os.startsWith("Linux")) + { + File file = new File(CHECK_USERPASS_FILE); + StringBuffer sb = new StringBuffer(); + sb.append(file.getCanonicalPath() + " " + Utils.getLocalIp()); + if (username != null) + { + sb.append(" " + username.trim()); + if (passwd != null) + { + sb.append(" " + DESUtil.desDecrypt(passwd.trim())); + } + } + sb.append(" >/dev/null 2>&1;"); + sb.append("echo $?"); + + String[] cmdArr = new String[] { "/bin/bash", "-c", sb.toString() }; + process = Runtime.getRuntime().exec(cmdArr); + process.getOutputStream().close(); + bReader = new BufferedReader(new InputStreamReader(process.getInputStream())); + errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); + String line = null; + while ((line = bReader.readLine()) != null) + { + logger.debug("checkUserPass line-------" + line); + if (line.trim().equals("0")) + { + flag = true; + } + } + while ((line = errorReader.readLine()) != null) + { + logger.debug("checkUserPass error line--->" + line); + } + } else + { + throw new IOException("unknown operating system: " + os); + } + + logger.debug("runExecGetResult end-------"); + + return flag; + } catch (Exception e) + { + throw e; + } finally + { + try + { + if (bReader != null) + { + bReader.close(); + } + if (errorReader != null) + { + errorReader.close(); + } + if (process != null) + { + process.destroy(); + } + } catch (Exception e1) + { + } + } + } + + /** + * 检查文件或命令是否存在且可执行 + * + * @param cmd + * @return true 是,false 否 + * @throws IOException + */ + public static boolean isFileOrCmdExist(String cmd) throws IOException + { + BufferedReader bReader = null; + BufferedReader errorReader = null; + Process process = null; + boolean flag = false; + logger.debug("isFileOrCmdExist start-------" + cmd); + try + { + // 根据操作系统确定运行方式 + String os = System.getProperty("os.name"); + if (os.startsWith("Windows")) + { + logger.debug("isFileOrCmdExist Windows-------" + cmd); + // 待实现: 目前只处理了文件,执行命令未实现判断 + File startFile = new File(cmd); + if (startFile.exists() && startFile.canExecute()) + { + flag = true; + } + } else if (os.startsWith("Linux")) + { + String cmd1 = "[ -x " + cmd + " ] || which " + cmd + ";echo $?"; + logger.debug("isFileOrCmdExist linux-------" + cmd1); + String[] shellCmd = new String[] { "/bin/bash", "-c", cmd1 }; + process = Runtime.getRuntime().exec(shellCmd); + process.getOutputStream().close(); + + bReader = new BufferedReader(new InputStreamReader(process.getInputStream())); + errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); + String line = null; + while ((line = bReader.readLine()) != null) + { + logger.debug("isFileOrCmdExist linux--->" + line); + if (line.trim().equals("0")) + { + flag = true; + } + } + while ((line = errorReader.readLine()) != null) + { + logger.debug("isFileOrCmdExist linux error--->" + line); + } + } else + { + throw new IOException("unknown operating system: " + os); + } + + } catch (Exception e) + { + logger.error(Utils.printExceptionStack(e)); + return false; + } finally + { + try + { + if (bReader != null) + { + bReader.close(); + } + if (errorReader != null) + { + errorReader.close(); + } + if (process != null) + { + process.destroy(); + } + } catch (Exception e1) + { + } + } + logger.debug("isFileOrCmdExist end-------" + cmd); + + return flag; + } + + /** + * + * TODO 处理路径中带有空格 括号的问题 在外部加入"" + * + * @author jinshujuan May 30, 2013 + * @version 1.0 + * @param str + * @return + */ + public static String handlerWinPath(String str) + { + + if (str != null && !str.equals("")) + { + if (str.indexOf(" ") != -1 || str.indexOf("(") != -1 || str.indexOf(")") != -1) + { + str = "\"" + str + "\""; + } + } + logger.debug("handlerWinPath---str=" + str); + return str; + } + + /** + * 对Windows下路径中带空格的特殊处理 + * + * @param str + * @return + */ + public static String handlerWinSpace(String str) + { + /* + * 注意::若最后一级路径出现空格,处理上的存在Bug -- 需要在最后一级也加上\\或/ 如:xcopy /y D:\\Program + * Files\\Test 1\\ D:\\Program Files\\Test 2\\ /s/e 可以正常替换空格 xcopy /y + * D:\\Program Files\\Test 1 D:\\Program Files\\Test 2 /s/e + * 不能正常替换空格,最后一级Test 1和Test 2中的空格替换不了。 + */ + if (str != null) + { + if (str.indexOf(":\\") != -1) + { + // 针对这样的命令, 如: + // D:\Program Files\Test\test.bat >> D:\Program Files\test.log; + // xcopy /y D:\Program Files\Test D:\Program Files\Test2 /s/e + // 先取第一个:\之后,每次再取与\之间的串循环替换空格 + // 若与\之间的串中有:\(/test.bat >> D:/, /Test D:/)则不用替换空格 + int index = str.indexOf(":\\"); + String start = str.substring(0, index + 2); + String end = str.substring(index + 2, str.length()); + while (end.indexOf("\\") != -1) + { + index = end.indexOf("\\"); + String middle = end.substring(0, index + 1); + if (middle.endsWith(":\\")) + { + start += middle; + } else + { + start += middle.replace(" ", "\" \""); + } + end = end.substring(index + 1, end.length()); + } + start += end; + str = start; + } else if (str.indexOf(":/") != -1) + { + // 针对这样的命令, 如: + // D:/Program Files/Test/test.bat >> D:/Program Files/test.log; + // xcopy /y D:/Program Files/Test D:/Program Files/Test2 /s/e + // 先取第一个:/之后,每次再取与/之间的串循环替换空格 + // 若与/之间的串中有:/(/test.bat >> D:/, /Test D:/)或 /(/Test2 /)则不用替换空格 + int index = str.indexOf(":/"); + String start = str.substring(0, index + 2); + String end = str.substring(index + 2, str.length()); + while (end.indexOf("/") != -1) + { + index = end.indexOf("/"); + String middle = end.substring(0, index + 1); + if (middle.endsWith(":/") || middle.endsWith(" /")) + { + start += middle; + } else + { + start += middle.replace(" ", "\" \""); + } + end = end.substring(index + 1, end.length()); + } + start += end; + str = start; + } + } + logger.debug("handlerWinSpace---str=" + str); + return str; + } + + /** + * 对Linux下路径中带空格的特殊处理 + * + * @param str + * @return + */ + public static String handlerLinuxSpace(String str) + { + if (str != null) + { + str = str.trim().replace(" ", "\\ "); + } + return str; + } + + /** + * 根据关键字查找进程PID + * + * @param procSearchKey + * @return pid列表 + * @throws Exception + */ + public static List getProcessIdBySearchKey(String procSearchKey) throws Exception + { + List value = null; + // 根据操作系统确定获取进程ID的方式 + String os = System.getProperty("os.name"); + if (os.startsWith("Windows")) + { + value = getWindowsProcessId(procSearchKey); + } else if (os.startsWith("Linux")) + { + value = getLinuxProcessId(procSearchKey); + } else + { + throw new IOException("unknown operating system: " + os); + } + + return value; + } + + /** + * Windows下根据关键字查找进程,关键字不区分大小写 + * + * @param procSearchKey + * @return + */ + public static List getWindowsProcessId(String procSearchKey) + { + // "wmic process get + // Caption,commandLine,Description,ExecutablePath,Name,processId|findstr + // /i " + procSearchKey + "|findstr /v findstr" + String[] cmd = new String[] { + "cmd.exe", + "/C", + "wmic process where \"Caption like '%%" + procSearchKey + + "%%' or CommandLine like '%%" + procSearchKey + + "%%' or Description like '%%" + procSearchKey + + "%%' or ExecutablePath like '%%" + procSearchKey + "%%' or Name like '%%" + + procSearchKey + + "%%'\" get Name,ProcessId,CommandLine|findstr /v wmic|findstr /v findstr" }; + logger.info("getWindowsProcessId-----" + cmd[2]); + BufferedReader bReader = null; + BufferedReader errorReader = null; + Process process = null; + List processIDList = null; + try + { + synchronized (oWin) + { + process = Runtime.getRuntime().exec(cmd); + process.getOutputStream().close(); + bReader = new BufferedReader(new InputStreamReader(process.getInputStream())); + errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); + String line = null; + processIDList = new ArrayList(); + while ((line = bReader.readLine()) != null) + { + logger.debug("getWindowsProcessId ---- line >> " + line); + String[] tmp = line.split("\\s{2,}"); + if (tmp == null) + { + continue; + } + for (int i = 0; i < tmp.length; i++) + { + if (tmp[i].matches("\\d+")) + { + processIDList.add(tmp[i]); + } + } + } + while ((line = errorReader.readLine()) != null) + { + logger.debug("getWindowsProcessId error line--->" + line); + } + } + + } catch (IOException e) + { + logger.error(Utils.printExceptionStack(e)); + return null; + } finally + { + try + { + if (bReader != null) + { + bReader.close(); + } + if (errorReader != null) + { + errorReader.close(); + } + if (process != null) + { + process.destroy(); + } + } catch (IOException e) + { + logger.error(Utils.printExceptionStack(e)); + } + } + + return processIDList; + } + + /** + * Linux下根据关键字查找进程,关键字不区分大小写 + * + * @param procSearchKey + * @return + */ + public static List getLinuxProcessId(String procSearchKey) + { + String cmd = "ps -ef | grep -i '" + procSearchKey.trim() + + "' | grep -v grep | awk '{print $2}'"; + logger.info("getLinuxProcessId-----" + cmd); + String[] shellCmd1 = new String[] { "/bin/bash", "-c", cmd }; + BufferedReader bReader = null; + BufferedReader errorReader = null; + Process process = null; + List processIDList = null; + synchronized (oLinux) + { + try + { + // 找到根据进程名获取到的进程号列表 + process = Runtime.getRuntime().exec(shellCmd1); + process.getOutputStream().close(); + + bReader = new BufferedReader(new InputStreamReader(process.getInputStream())); + errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); + String line = null; + processIDList = new ArrayList(); + while ((line = bReader.readLine()) != null) + { + processIDList.add(line); + logger.debug("getLinuxProcessId ---- line >> " + line); + } + while ((line = errorReader.readLine()) != null) + { + logger.debug("getLinuxProcessId error line--->" + line); + } + } catch (IOException e) + { + logger.error(Utils.printExceptionStack(e)); + } finally + { + try + { + if (bReader != null) + { + bReader.close(); + } + if (errorReader != null) + { + errorReader.close(); + } + if (process != null) + { + process.destroy(); + } + } catch (IOException e) + { + logger.error(Utils.printExceptionStack(e)); + } + } + + } + return processIDList; + } + + /** + * 检查PID是否存在,存在返回PID,不存在返回描述信息 + * 检查逻辑:先检查PID文件,取出PID,验证PID指定进程是否存在,不存在再使用搜索关键字查找进程 isExistFlag: 0 进程不存在,1 + * 进程存在且仅找到一个,2 进程存在且找到多个 + * + * @return 数组:{进程是否存在的标识(0|1|2), 进程PID或者描述信息} + */ + public static Object[] checkPidAndGetPid(String pidFile, String procSearchKey) throws Exception + { + int isExistFlag = 0; + String pidInfo = ""; + if (pidFile != null && !"".equals(pidFile)) + { + File file = new File(pidFile); + if (file.exists()) + { + String[] pidArr = ProcessUtil.getProcessIdByFile(file); + if (pidArr != null && pidArr.length > 0) + {// 目前考虑只有一个PID的情况 + boolean isExist = ProcessUtil.isProcessExistByPid(pidArr[0]); + if (isExist) + { + pidInfo = pidArr[0]; + isExistFlag = 1; + } else + { +// pidInfo = "进程PID\"" + pidArr[0] + "\"不存在"; + pidInfo = "i18n_client.ProcessUtil.processPid_n81i\"" + pidArr[0] + "\"i18n_client.ProcessUtil.notExists_n81i"; + } + } + } else + { +// pidInfo = "PID文件\"" + file.getAbsolutePath() + "\"不存在"; + pidInfo = "i18n_client.ProcessUtil.pidFile_n81i\"" + file.getAbsolutePath() + "\"i18n_client.ProcessUtil.notExists_n81i"; + } + } else + { +// pidInfo = "PID文件字段为空"; + pidInfo = "i18n_client.ProcessUtil.pidFieldNull_n81i"; + } + + if (isExistFlag == 0 && procSearchKey != null && !"".equals(procSearchKey)) + { + // PID文件或PID文件中的PID不存在,则使用进程搜索关键字查找PID + List pidList = ProcessUtil.getProcessIdBySearchKey(procSearchKey); + if (pidList == null || pidList.size() == 0) + { +// pidInfo += (pidInfo.length() > 0 ? ", " : "") + "进程搜索关键字" + procSearchKey + "未找到进程"; + pidInfo += (pidInfo.length() > 0 ? ", " : "") + "i18n_client.ProcessUtil.searchKey_n81i" + procSearchKey + "i18n_client.ProcessUtil.noProcess_n81i"; + } else if (pidList.size() > 1) + { + pidInfo += (pidInfo.length() > 0 ? ", " : "") + "i18n_client.ProcessUtil.searchKey_n81i" + procSearchKey + + " i18n_client.ProcessUtil.findTooMuch_n81i"; + isExistFlag = 2; + } else + {// 只找到一个进程 + pidInfo = pidList.get(0); + isExistFlag = 1; + } + } + + return new Object[] { isExistFlag, pidInfo }; + } + + /* + * public static String getProcessId(String processName, String processPath) + * throws Exception{ String value = null; //根据操作系统确定获取进程ID的方式 String os = + * System.getProperty("os.name"); if (os.startsWith("Windows")) { value = + * getWindowsProcessId(processName, processPath); }else if + * (os.startsWith("Linux")){ value = getLinuxProcessId(processName, + * processPath); } else { throw new IOException("unknown operating system: " + + * os); } + * + * return value; } + * + * public static String getWindowsProcessId(String procName, String + * procPath) { String[] cmd = new String[] { "cmd.exe", "/C", "wmic process + * where \"name='" + procName.trim() + "' and executablepath='" + + * procPath.trim().replace("\\", "\\\\") + "'\" get processid" };// list + * full logger.debug("cmd-----"+cmd[2]); BufferedReader bReader = null; + * Process process = null; String processId = null; try { synchronized + * (oWin) { process = Runtime.getRuntime().exec(cmd); + * process.getOutputStream().close(); bReader = new BufferedReader(new + * InputStreamReader(process .getInputStream())); String line = null; while + * ((line = bReader.readLine()) != null) { logger.debug("line-----" + line); + * if (line.trim().matches("\\d+")) { processId = line.trim(); } } } } catch + * (IOException e) { logger.error(Utils.printExceptionStack(e)); return + * processId; }finally{ try { if (bReader != null) { bReader.close(); } if + * (process != null) { process.destroy(); } } catch (IOException e) { + * logger.error(Utils.printExceptionStack(e)); } } + * + * return processId; } + * + * public static String getLinuxProcessId(String procName, String procPath) { + * String cmd = "ps -ef | grep '" + procName.trim() + "' | grep -v grep | + * awk '{print $2}'"; String[] shellCmd1 = new String[] { "/bin/bash", "-c", + * cmd }; String[] shellCmd2 = new String[] { "/bin/bash", "-c", cmd }; + * BufferedReader bReader = null; List processIDList = null; + * Process process = null; synchronized (oLinux) { try { // 找到根据进程名获取到的进程号列表 + * process = Runtime.getRuntime().exec(shellCmd1); + * process.getOutputStream().close(); + * + * bReader = new BufferedReader(new InputStreamReader(process + * .getInputStream())); String line = null; processIDList = new ArrayList(); + * while ((line = bReader.readLine()) != null) { processIDList.add(line); } } + * catch (IOException e) { logger.error(Utils.printExceptionStack(e)); } + * finally { try { if (bReader != null) { bReader.close(); } if (process != + * null) { process.destroy(); } } catch (IOException e) { + * logger.error(Utils.printExceptionStack(e)); } } + * + * for (int i = 0; i < processIDList.size(); i++) { shellCmd2 = new String[] { + * "/bin/bash", "-c", "lsof -p " + processIDList.get(i) + " | grep 'txt' + * |grep -v grep | awk '{print $NF}'" }; try { process = + * Runtime.getRuntime().exec(shellCmd2); process.getOutputStream().close(); + * bReader = new BufferedReader(new InputStreamReader(process + * .getInputStream())); String line = null; while ((line = + * bReader.readLine()) != null) { if (line.trim().equals(procPath.trim())) + * return processIDList.get(i); } } catch (IOException e) { + * logger.error(Utils.printExceptionStack(e)); } finally { try { if (bReader != + * null) { bReader.close(); } if (process != null) { process.destroy(); } } + * catch (IOException e) { logger.error(Utils.printExceptionStack(e)); } } + * }//for end } return null; } + */ + +} diff --git a/src/com/nis/nmsclient/util/RarUtil.java b/src/com/nis/nmsclient/util/RarUtil.java new file mode 100644 index 0000000..d394411 --- /dev/null +++ b/src/com/nis/nmsclient/util/RarUtil.java @@ -0,0 +1,125 @@ +package com.nis.nmsclient.util; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.io.IOUtils; +import org.apache.log4j.Logger; + +import de.innosystec.unrar.Archive; +import de.innosystec.unrar.rarfile.FileHeader; + +/** + * 对rar进行解压缩 + * + */ +public class RarUtil { + static Logger logger = Logger.getLogger(RarUtil.class); + /** + * 对单个rar压缩包解压 + * @param rarFileName 需要解压的rar文件 + * @param destDir 解压后的目标目录 + * @throws Exception + */ + public static void unRar(String rarFileName, String destDir) + throws Exception { + logger.debug("unRar start……"); + Archive archive = null; + FileHeader fh = null; + try { + logger.debug("unRar rarFileName---" + rarFileName); + logger.debug("unRar destDir---" + destDir); + File file = new File(rarFileName); + if(!file.exists()){ +// throw new Exception("解压源文件不存在: " + file.getAbsolutePath()); + throw new Exception("Unzip source file does not exist: " + file.getAbsolutePath()); + } + logger.debug("unRar: get archive……"); + archive = new Archive(file); + logger.debug("unRar: archive =" + archive); + if (archive != null) { + logger.debug("unRar: while start"); + int index = 0; + while ((fh = archive.nextFileHeader()) != null) { + logger.debug("unRar: " + ++index + " start"); + String fileName = fh.getFileNameW().trim(); + if (!existZH(fileName)) { + fileName = fh.getFileNameString().trim(); + } + String path = (destDir + File.separator + fileName) + .replaceAll("\\\\", "/"); + + logger.debug("unRar: path---" + path); + if (fh.isDirectory()) { + //logger.debug("unRar: FileHeader is directory"); + int end = path.lastIndexOf("/"); + if (end != -1) { + File dir = new File(path.substring(0, end)); + if (!dir.exists()) { + dir.mkdirs(); + } + } + }else{ + //logger.debug("unRar: FileHeader is file"); + FileOutputStream os = null; + try{ + File out = new File(path); + if(!out.getParentFile().exists()){ + out.getParentFile().mkdirs(); + } + os = new FileOutputStream(out); + archive.extractFile(fh, os); + }catch (Exception e) { + throw e; + }finally{ + fh = null; + if (os != null) { + os.close(); + os = null; + } + } + } + logger.debug("unRar: " + index + " end"); + } + logger.debug("unRar: while end"); + } + logger.debug("unRar end……"); + } catch (Exception e) { + throw e; + } finally { + fh = null; + try { + if (archive != null) { + archive.close(); + archive = null; + } + } catch (IOException e) { + e.printStackTrace(); + } + + } + + } + + public static boolean existZH(String str) { + String regEx = "[\\u4e00-\\u9fa5]"; + Pattern p = Pattern.compile(regEx); + Matcher m = p.matcher(str); + while (m.find()) { + return true; + } + return false; + } + + public static void main(String[] args) { + try { + unRar("D:\\temp\\logs.rar", "D:\\temp\\log"); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/src/com/nis/nmsclient/util/StringUtil.java b/src/com/nis/nmsclient/util/StringUtil.java new file mode 100644 index 0000000..cf0b551 --- /dev/null +++ b/src/com/nis/nmsclient/util/StringUtil.java @@ -0,0 +1,528 @@ +/* + * @(#)StringUtil.java 1.0 + * + * Copyright 2010 NIS, Inc. All rights reserved. + * + */ +package com.nis.nmsclient.util; + +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.security.MessageDigest; +import java.util.Collection; +import java.util.Map; +import java.util.UUID; + +import sun.misc.BASE64Encoder; + + +/** +* +*

字符串处理工具类.

+* @author 中科智源育成信息有限公司 E-mail: doufengh@software.ict.ac.cn +* @version 1.0 创建时间:Nov 2, 2010 2:57:56 PM +* +*/ +public final class StringUtil { + /** + * ISO8859_1 编码集 + */ + public static final String CODE_ISO8859_1 = "ISO8859_1"; + /** + * GB2312 编码集 + */ + public static final String CODE_GB2312 = "GB2312"; + /** + * GBK 编码集 + */ + public static final String CODE_GBK = "GBK"; + /** + * UTF-8 编码集 + */ + public static final String CODE_UTF_8 = "UTF-8"; + + private static int size = 0; + + private static final String[] SIMPLIFIED_CASE = { "O", "一", "二", "三", "四", "五", + "六", "七", "八", "九", "十" }; +// private static final String[] SIMPLIFIED_CASE = { "Zero", "One", "Two", "Three", "Four", "Five", +// "Six", "Seven", "Eight", "Nine", "Ten" }; + + private static final String[] TRADITIONAL_CASE = { "零", "壹", "贰", "叁", "肆", "伍", + "陆", "柒", "捌", "玖", "拾" }; +// private static final String[] TRADITIONAL_CASE = { "Zero", "One", "Two", "Three", "Four", "Five", +// "Six", "Seven", "Eight", "Nine", "Ten" }; + + /** + *

Description:抑制默认的构造器,避免实例化对象

+ */ + private StringUtil() { + + } + + /** + * + *

判断一个对象是否为空

+ *

+ * object元素判断所有对象是否为空. + * 另外对{@link String}、{@link Collection} 、{@link Map} 进行长度验证,如果长度为0,视为空对象. + *

+ *
+	* String aa = " ";
+	* List list = new ArrayList()
+	* LinkedHashSet set = new LinkedHashSet();
+	* StringUtil.isEmpty(aa) = true
+	* StringUtil.isEmpty(list) = true
+	* StringUtil.isEmpty(set) = true
+	* StringUtil.isEmpty("\t") = true
+	* 
+ * @param object 对象元素 + * @return true 对象为null,false 对象不为null. + */ + public static boolean isEmpty(Object object) { + initSize(object); + return size==0; + + } + + + /** + * + * 判断对象是否有数据存在? 不存在为0、存在不为0的值. + * @param object 对象值 + */ + private static void initSize(Object object){ + + if (object == null) { + size = 0; + } else { + if (object instanceof String) { + size = ((String)object).trim().length(); + } else if (object instanceof Collection) { + size = ((Collection)object).size(); + } else if (object instanceof Map) { + size = ((Map)object).size(); + //其他数据类型 + } else { + size = 1; + } + + } + + } + + /** + * + *

如果对象为空时,返回默认值.

+ * @param object 要判断是否为空的对象 + * @param defaultValue 为空时设的默认值 + * @see #isEmpty(Object) + * @return 获取处理后的数据 + */ + public static Object setDefaultValueIfNull(Object object,Object defaultValue){ + if(isEmpty(object)){ + return defaultValue; + } + return object; + } + + /** + * + *

对字符串进行MD5加密.

+ *

+ * 一般作为密码的处理方式,首先通过MD5进行加密,然后将字符串进行Base64编码获得所需字符. + *

+ *
+	* String str = "ceshi";
+	* StringUtil.md5(str) = "zBfDDNERxyFfyPUfh5Dg4Q=="
+	* 
+ * @param msg 要加密的字符串 + * @return 返回加密后的25位字符,如果解析出现异常将返回null. + */ + public static String md5(String msg) { + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + byte[] b = md.digest(msg.getBytes()); + BASE64Encoder encoder = new BASE64Encoder(); + String code = encoder.encode(b); + return code; + } catch (Exception e) { + return null; + } + + } + + /** + *

截取处理字符串,当字符串超过指定的截取长度时,用“......”补充

+ *
+	* String str = "中华人民共和国";
+	* StringUtil.getMoreString(str, 6) = "中华人民共和......"
+	* 
+ * @param text 字符串数据 + * @param length 截取的长度值 + * @return 返回处理后字符 + */ + public static String getMoreString(String text,int length){ + StringBuilder textBuilder = new StringBuilder(); + + if(isEmpty(text)){ + return null; + } + if(text.length()>length){ + text = text.substring(0,length); + textBuilder.append(text).append("......"); + }else { + textBuilder.append(text); + } + + + return textBuilder.toString(); + } + + + /** + * + *

通过给定url获取域名地址.

+ *

+ * 获得域名信息需去除 http/https/ftp 与 www 一些头信息,获取有效地址. + *

+ *
+	* StringUtil.getDomain("http://www.baidu.com") = "baidu.com"
+	* 
+ * @param webSiteUrl url 地址 + * @return 返回截取后的域名地址 + */ + public static String getDomain(String webSiteUrl) { + String url = ""; + + if(isEmpty(webSiteUrl)){ + return url; + } + + + if (webSiteUrl.indexOf("http://") >= 0) { + url = webSiteUrl.substring("http://".length(), webSiteUrl.length()); + } else if (webSiteUrl.indexOf("https://", 0) >= 0) { + url = webSiteUrl.substring("https://".length(), webSiteUrl.length()); + } else if (webSiteUrl.indexOf("ftp://", 0) >= 0) { + url = webSiteUrl.substring("ftp://".length(), webSiteUrl.length()); + } else { + url = webSiteUrl; + } + + if (url.indexOf("/", 0) >= 0) { + url = url.substring(0, url.indexOf("/", 1)); + } + if (url.indexOf("www.") == 0) { + url = url.substring(url.indexOf(".") + 1, url.length()); + } + if (url.indexOf("?") >= 0) { + url = url.substring(0, url.indexOf("?")); + } + + return url; + } + + /** + * + *

按照给定规则分隔字符串

+ *
例子说明:
+ * @param str 需要分隔的字符串 + * @param regex 分隔规则 + * @return 返回字符串数组,如果分隔字符串为空返回null. + */ + public static String[] Split(String str,String regex) { + + if(StringUtil.isEmpty(str)){ + return null; + } + + return str.split(regex); + + } + + /** + * + *

字符编码转换,需要提供字符串的源编码格式.

+ *

+ * 字符串工具类中提供一些字符编码常量: + * {@link #CODE_GB2312}\{@link #CODE_GBK}\{@link #CODE_ISO8859_1}\{@link #CODE_UTF_8} + *

+ * @param value 要编码的值 + * @param sourceCodingFormat 字符的原始编码格式,具体编码格式可看本类提供的编码样式. + * @param destCodingFormat 要转换字符的编码格式,具体编码格式可看本类提供的编码样式. + * @return 返回编码后的字符串. + * @throws UnsupportedEncodingException + */ + public static String getCodingConversionResult(String value,String sourceCodingFormat, + String destCodingFormat ) throws UnsupportedEncodingException{ + + if(isEmpty(value)){ + return null; + } + + + return new String(value.getBytes(sourceCodingFormat), destCodingFormat); + } + + /** + * + *

将url转为utf编码格式url,当url符合utf8格式,不会转换.

+ *
+	* StringUtil.getUTF8URLEncode("http://www.baidu.com/s?param='中国'") = 
+	*   "http%3A%2F%2Fwww.baidu.com%2Fs%3Fparam%3D%27%E4%B8%AD%E5%9B%BD%27"
+	* 
+ * @see #getUTF8URLDecode(String) + * @param url 字符串url + * @return 返回utf8转换后的字符url + * @throws UnsupportedEncodingException + */ + public static String getUTF8URLEncode(String url)throws UnsupportedEncodingException{ + if(isUtf8Url(url)){ + return url; + } + + return URLEncoder.encode(url, StringUtil.CODE_UTF_8); + + } + + /** + * + *

将utf8编码的url解析为原始url.当url不符合utf8格式时,不转换.

+ *
例子说明:
+ * @see #getUTF8URLEncode(String) + * @param url 字符串url + * @return 返回解析后字符url + * @throws UnsupportedEncodingException + */ + + public static String getUTF8URLDecode(String url)throws UnsupportedEncodingException{ + + /*if(!isUtf8Url(url)){ + return url; + }*/ + + return URLDecoder.decode(url, StringUtil.CODE_UTF_8); + + } + + + /** * 编码是否有效 + * @param text + * @return + */ + private static boolean Utf8codeCheck(String text){ + String sign = ""; + if (text.startsWith("%e")){ + + for (int i = 0, p = 0; p != -1; i++) { + p = text.indexOf("%", p); + + if (p != -1){ + p++; + } + sign += p; + } + } + + return sign.equals("147-1"); + } + + /** + * 是否Utf8Url编码 + * @param text + * @return true or false + */ + private static boolean isUtf8Url(String text) { + text = text.toLowerCase(); + int p = text.indexOf("%"); + + if (p != -1 && text.length() - p > 9) { + text = text.substring(p, p + 9); + } + + return Utf8codeCheck(text); + } + + + /** + * + *

判断字符串是否是数字格式(包括小数形式).

+ *
+    * String a1 = "12";
+	* String a2 = "0.01";
+	* String a3 = "0.0.1";
+	* String a4 = "123a";
+	* StringUtil.isNumeric(a1) = true
+	* StringUtil.isNumeric(a2) = true
+	* StringUtil.isNumeric(a3) = false
+	* StringUtil.isNumeric(a4) = false
+    * 
+ * @param numberString 数字格式字符串 + * @return true 符合数字格式(包括小数),false 不符合数字格式. + */ + public static boolean isNumeric(String numberString){ + + if(isEmpty(numberString)){ + return false; + } + + if(numberString.startsWith(".")||numberString.endsWith(".")){ + return false; + } + + int length = numberString.split("\\.").length-1; //判断小数点在字符串中出现的次数。 + + + if(length>1) { //小数点大于1次,不符合数字规范 + + return false; + } + + + for(int i=0; i将字符串数字转换为简体大写中文格式.

+ *
+    * StringUtil.convertSimplifiedCase("325") = ”三二五"
+    * 
+ * @param numberString 数字字符串 + * @return 返回简体大写后的数字 + */ + public static String convertSimplifiedCase(String numberString) { + + StringBuilder simplifiedBuilder = new StringBuilder(); + + if(isEmpty(numberString)){ + return null; + } + + + for (int i = 0; i < numberString.length(); i++) { + String tempNumberString = String.valueOf(numberString.charAt(i)); + if ("0123456789".indexOf(tempNumberString) >= 0) { + int number = Integer.parseInt(tempNumberString); + simplifiedBuilder.append(SIMPLIFIED_CASE[number]); + } else { + simplifiedBuilder.append(tempNumberString); + } + } + + return simplifiedBuilder.toString(); + } + + + /** + * + *

把字符串中的数字转换成繁体大写中文的格式.

+ *
+    * StringUtil.convertTraditionalCase("325") = "叁贰伍"
+    * 
+ * @param numberString 数字字符串 + * @return 返回繁体大写后的数字 + */ + public static String convertTraditionalCase(String numberString) { + + StringBuilder simplifiedBuilder = new StringBuilder(); + + if(isEmpty(numberString)){ + return null; + } + + + for (int i = 0; i < numberString.length(); i++) { + String tempNumberString = String.valueOf(numberString.charAt(i)); + if ("0123456789".indexOf(tempNumberString) >= 0) { + int number = Integer.parseInt(tempNumberString); + simplifiedBuilder.append(TRADITIONAL_CASE[number]); + } else { + simplifiedBuilder.append(tempNumberString); + } + } + + return simplifiedBuilder.toString(); + } + + /** + * + *

创建唯一标识字符串.

+ *
+   * StringUtil.createUUID() = "00000DAF3CFC4E0B8DF2D5BEACB14D75" 
+   * 
+ * @return 返回标识符字符串 + */ + public static String createUUID() { + String uuid = UUID.randomUUID().toString(); + uuid = uuid.replace("-", ""); + return uuid.toUpperCase(); + } + + + /** + * + *

字符串过滤,负责将html的textarea属性获得的字符转换成html格式的字符集.

+ * @param str 要解析的字符串 + * @return 是解析后的字符串 + */ + public static String htmlFilter(String str) { + StringBuffer stringbuffer = new StringBuffer(); + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + switch (c) { + + case 39: + stringbuffer.append("'"); + break; + + case 34: + stringbuffer.append("""); + break; + + case 60: + stringbuffer.append("<"); + break; + + case 62: + stringbuffer.append(">"); + break; + + case 38: + stringbuffer.append("&"); + break; + + case 32: + stringbuffer.append(" "); + break; + + case 10: + stringbuffer.append("
"); + break; + + case 8220: + stringbuffer.append("“"); + break; + + case 8221: + stringbuffer.append("”"); + break; + + default: + stringbuffer.append(c); + break; + } + } + + return stringbuffer.toString(); + } + +} diff --git a/src/com/nis/nmsclient/util/Utils.java b/src/com/nis/nmsclient/util/Utils.java new file mode 100644 index 0000000..97d5497 --- /dev/null +++ b/src/com/nis/nmsclient/util/Utils.java @@ -0,0 +1,323 @@ +package com.nis.nmsclient.util; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.util.Enumeration; +import java.util.regex.Pattern; + +import org.apache.log4j.Logger; + +public class Utils { + static Logger logger = Logger.getLogger(Utils.class); + + /** + * 获得本机IP + * + * @return + */ + public static String getLocalIp() { + String nativeip = ""; + try { + //根据操作系统确定获取进程ID的方式 + String os = System.getProperty("os.name"); + if (os.startsWith("Windows")) { + InetAddress ipv4 = InetAddress.getLocalHost(); + nativeip = ipv4.getHostAddress().toString(); + logger.debug("------getLocalIp--nativeip=" + nativeip); + }else if (os.startsWith("Linux")){ + InetAddress ip = null; + boolean findIp = false; + // 根据网卡取本机配置的IP + Enumeration netInterfaces = NetworkInterface.getNetworkInterfaces(); + while (netInterfaces.hasMoreElements()) { + if (findIp) { + break; + } + NetworkInterface ni = netInterfaces.nextElement(); + logger.debug("------getLocalIp--NetWorkName=" + ni.getName()); + Enumeration ips = ni.getInetAddresses(); + while (ips.hasMoreElements()) + ip = ips.nextElement(); + logger.debug("------getLocalIp--ip.isSiteLocalAddress()=" + + ip.isSiteLocalAddress()); + logger.debug("------getLocalIp--ip.isLoopbackAddress()=" + + ip.isLoopbackAddress()); + logger.debug("------getLocalIp--HostAddress=" + + ip.getHostAddress()); + if (ip.isSiteLocalAddress() && !ip.isLoopbackAddress() + && ip.getHostAddress().indexOf(":") == -1) { + findIp = true; + logger.debug("------findIp--" + ip.getHostAddress()); + break; + } + } + if (ip != null) { + nativeip = ip.getHostAddress(); + } + } else { + throw new IOException("unknown operating system: " + os); + } + + } catch (Exception e) { + logger.error(Utils.printExceptionStack(e)); + } + + return nativeip; + } + + public static String getOperateSystem() { + BufferedReader bReader = null; + BufferedReader errorReader = null; + Process process = null; + try { + String os = System.getProperty("os.name");//根据操作系统确定运行方式 + String[] cmdArr = null; + if (os.startsWith("Windows")) { + cmdArr = new String[] { "cmd.exe", "/C", "ver"}; + } else if (os.startsWith("Linux")) { + cmdArr = new String[] { "/bin/bash", "-c", "uname -r;uname -i;lsb_release -d| cut -d: -f2| cut -f2" }; + } else { + throw new IOException("unknown operating system: " + os); + } + process = Runtime.getRuntime().exec(cmdArr); + process.getOutputStream().close(); + bReader = new BufferedReader(new InputStreamReader(process + .getInputStream())); + errorReader = new BufferedReader(new InputStreamReader(process + .getErrorStream())); + String line = null; + StringBuffer sb = new StringBuffer(); + while ((line = bReader.readLine()) != null) { + if(line.trim().length()>0){ + sb.append(line.trim() + ","); + logger.debug("getOperateSystem right-->" + line); + } + } + while ((line = errorReader.readLine()) != null) { + logger.debug("getOperateSystem error-->" + line); + } + if(sb.length() > 0) { + if (os.startsWith("Windows")) { + String osInfo = System.getProperty("sun.arch.data.model");//32位 or 64 位 + sb.append(osInfo+"i18n_client.Utils.bit_n81i"); + }else { + sb.deleteCharAt(sb.length()-1);//去掉最后一个逗号 + } + } + + + return sb.toString(); + } catch (Exception e) { + logger.error("Get the exception of the operating system and the release version", e); + } finally { + try { + if (bReader != null) { + bReader.close(); + } + if (errorReader != null) { + errorReader.close(); + } + if (process != null) { + process.destroy(); + } + } catch (Exception e1) { + } + } + + return null; + } + + public static boolean checkIP(String checkStr) { + try { + String number = checkStr.substring(0, checkStr.indexOf('.')); + if (Integer.parseInt(number) > 255 || Integer.parseInt(number) < 0) { + return false; + } + checkStr = checkStr.substring(checkStr.indexOf('.') + 1); + number = checkStr.substring(0, checkStr.indexOf('.')); + if (Integer.parseInt(number) > 255 || Integer.parseInt(number) < 0) { + return false; + } + + checkStr = checkStr.substring(checkStr.indexOf('.') + 1); + number = checkStr.substring(0, checkStr.indexOf('.')); + if (Integer.parseInt(number) > 255 || Integer.parseInt(number) < 0) { + return false; + } + number = checkStr.substring(checkStr.indexOf('.') + 1); + if (Integer.parseInt(number) > 255 || Integer.parseInt(number) < 0) { + return false; + } else { + return true; + } + } catch (Exception e) { + return false; + } + } + + //测试IP地址是否合法 + public static boolean isIp(String ipAddress){ +// String test = "([1-9]|[1-9]\\d|1\\d{2}|2[0-1]\\d|22[0-3])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}"; +// Pattern pattern = Pattern.compile(test); +// Matcher matcher = pattern.matcher(ipAddress); +// return matcher.matches(); + String regex0 = "(2[0-4]\\d)" + "|(25[0-5])"; + String regex1 = "1\\d{2}"; + String regex2 = "[1-9]\\d"; + String regex3 = "\\d"; + String regex = "(" + regex0 + ")|(" + regex1 + ")|(" + regex2 + ")|(" + regex3 + ")"; + regex = "(" + regex + ").(" + regex + ").(" + regex + ").(" + regex + ")"; + String[] str = ipAddress.split("\\.");//根据@拆分IP地址 + if (!Pattern.matches(regex, ipAddress)) + return false; + else if(str!=null && str.length!=4){//如果IP地址拆分后的数组长度不为4则不是正确的IP地址 + return false; + }else{ + return true; + } + } + public static long ipToLong(String strIP) + //将127.0.0.1 形式的IP地址转换成10进制整数,这里没有进行任何错误处理 + { + int j=0; + int i=0; + long [] ip=new long[4]; + int position1=strIP.indexOf("."); + int position2=strIP.indexOf(".",position1+1); + int position3=strIP.indexOf(".",position2+1); + ip[0]=Long.parseLong(strIP.substring(0,position1)); + ip[1]=Long.parseLong(strIP.substring(position1+1,position2)); + ip[2]=Long.parseLong(strIP.substring(position2+1,position3)); + ip[3]=Long.parseLong(strIP.substring(position3+1)); + return (ip[0]<<24)+(ip[1]<<16)+(ip[2]<<8)+ip[3]; + } + public static String longToIP(long longIP) + //将10进制整数形式转换成127.0.0.1形式的IP地址,按主机序 + { + StringBuffer sb=new StringBuffer(""); + sb.append(String.valueOf(longIP>>>24&0xFF));//直接右移24位 + sb.append("."); //将高8位置0,然后右移16位 + sb.append(String.valueOf((longIP&0x00FFFFFF)>>>16)); + sb.append("."); + sb.append(String.valueOf((longIP&0x0000FFFF)>>>8)); + sb.append("."); + sb.append(String.valueOf(longIP&0x000000FF)); + //sb.append("."); + return sb.toString(); + } + //将10进制整数形式转换成127.0.0.1形式的IP地址,按网络序 + public static String longToNetIp(long longIP){ + StringBuffer sb=new StringBuffer(""); + sb.append(String.valueOf(longIP&0x000000FF)); + sb.append("."); + sb.append(String.valueOf((longIP&0x0000FFFF)>>>8)); + sb.append(".");//将高8位置0,然后右移16位 + sb.append(String.valueOf((longIP&0x00FFFFFF)>>>16)); + sb.append("."); + sb.append(String.valueOf(longIP>>>24&0xFF));//直接右移24位 + //sb.append("."); + return sb.toString(); + } + public static long netIpToLong(String strIP) + //将127.0.0.1 形式的IP地址转换成10进制整数,这里没有进行任何错误处理 + { + int j=0; + int i=0; + long [] ip=new long[4]; + int position1=strIP.indexOf("."); + int position2=strIP.indexOf(".",position1+1); + int position3=strIP.indexOf(".",position2+1); + ip[0]=Long.parseLong(strIP.substring(0,position1)); + ip[1]=Long.parseLong(strIP.substring(position1+1,position2)); + ip[2]=Long.parseLong(strIP.substring(position2+1,position3)); + ip[3]=Long.parseLong(strIP.substring(position3+1)); + return (ip[0])+(ip[1]<<8)+(ip[2]<<16)+(ip[3]<<24); + } + public static void main(String argus[]){ + System.out.println(Utils.checkIP("10.a.1.1")); + System.out.println(Utils.isIp("10.1.1.1")); + } + + + public static String printExceptionStack(Exception e){ + StackTraceElement[] ste = e.getStackTrace(); + StringBuffer sb = new StringBuffer(); + sb.append("\n\t" + e.toString() + "\n"); + for(StackTraceElement element : ste){ + sb.append("\t" + element.toString() + "\n"); + } + + return sb.toString(); + } + + + /** + * 根据网口名称获取此网口的Ip地址 + * @param ethName + * @return + */ + public static String getIpAddressByEthName(String ethName) { + String ip = null; + try { + //根据端口名称获取网卡信息 + NetworkInterface netWork = NetworkInterface.getByName(ethName); + //获取此网卡的ip地址,可能包含ipv4和ipv6 + Enumeration adds = netWork.getInetAddresses(); + while (adds.hasMoreElements()) { + InetAddress add = adds.nextElement(); + String ipStirng = add.getHostAddress(); + // 如果Ip地址长度大于16,说明是ipv6格式地址 + if (ipStirng.length() > 16) { + continue; + } + ip = ipStirng; + } + } catch (Exception e) { + logger.error("Getting IP address failure based on port name",e); + } + return ip; + } + + /** + * 根据ip地址查找端口的名字 + * + * @param ip + * @return + */ + public static String getNetInterfaceNameByIp(String ip) { + byte[] ipArr = Utils.ipStringToByte(ip); + String name = null; + try { + NetworkInterface local = NetworkInterface + .getByInetAddress(InetAddress.getByAddress(ipArr)); + name = local.getName(); + } catch (Exception e) { + logger.error("Getting port name failure based on IP address", e); + } + return name; + } + + /** + * 将string类型的ip地址,转换成数组类型,只支持ipv4 + * + * @param ip + * @return + */ + public static byte[] ipStringToByte(String ip) { + if (!Utils.isIp(ip)) { + logger.error("IP is not legal, can not be converted!"); + return null; + } + String[] ipArr = ip.split("\\."); + byte[] result = new byte[4]; + for (int i = 0; i < ipArr.length; i++) { + int tem = Integer.parseInt(ipArr[i]); + result[i] = (byte) tem; + } + return result; + } + +} diff --git a/src/com/nis/nmsclient/util/ZipUtil.java b/src/com/nis/nmsclient/util/ZipUtil.java new file mode 100644 index 0000000..ee8e984 --- /dev/null +++ b/src/com/nis/nmsclient/util/ZipUtil.java @@ -0,0 +1,321 @@ +package com.nis.nmsclient.util; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Enumeration; + +import org.apache.commons.io.IOUtils; +import org.apache.log4j.Logger; +import org.apache.tools.zip.ZipEntry; +import org.apache.tools.zip.ZipFile; +import org.apache.tools.zip.ZipOutputStream; + +import com.nis.nmsclient.thread.socket.CommonSocket; +import com.nis.nmsclient.thread.socket.ServerCollectData; + +public class ZipUtil { + static Logger logger = Logger.getLogger(ZipUtil.class); + /** + * java 解压缩单个zip压缩包 存在文件和目录的汉字处理问题 + * + * @param zipFileName 需要解压的压缩包文件 + * @param destDir 解压缩后的目标路径 + * @throws Exception + */ + public static void unZip(String zipFileName, String destDir) throws Exception { + logger.debug("unZip start……"); + ZipFile zipFile = null; + try{ + zipFile = new ZipFile(zipFileName); + Enumeration en = zipFile.getEntries(); + ZipEntry zipEntry = null; + while (en.hasMoreElements()) { + zipEntry = (ZipEntry) en.nextElement(); + String path = (destDir + File.separator + zipEntry.getName()).replaceAll("\\\\", "/"); + if (zipEntry.isDirectory()) {// 如果得到的是目录 + int end = path.lastIndexOf("/"); + if (end != -1) { + File dir = new File(path.substring(0, end)); + if (!dir.exists()) { + dir.mkdir(); + } + } + } else { + InputStream in = null; + FileOutputStream out = null; + try{ + File f = new File(path); + if(!f.getParentFile().exists()){ + f.getParentFile().mkdirs(); + } + f.createNewFile(); + in = zipFile.getInputStream(zipEntry); + out = new FileOutputStream(f); + IOUtils.copy(in, out); + }catch (Exception e) { + throw e; + }finally{ + if(in!=null) in.close(); + if(out!=null) out.close(); + } + } + }// while end + } catch (Exception e) { + throw e; + }finally { + if(zipFile != null){ + zipFile.close(); + zipFile = null; + } + } + logger.debug("unZip end……"); + } + + /** + * 将单个文件或一个目录打成zip包 + * + * @param srcDir 需要压压缩的文件目录 + * @param destFile 压缩后的目标文件 + * @throws Exception + */ + public static void zip(String srcDir, String destFile, String[] excludes) throws Exception { + ZipOutputStream out = null; + try{ + out = new ZipOutputStream(new FileOutputStream(destFile)); + //out.setEncoding("GBK");//解决linux乱码 + File srcFile = new File(srcDir); + if (!srcFile.exists()) { +// throw new Exception("压缩目录或文件不存在: " + srcFile.getAbsolutePath()); + throw new Exception("Compressed directories or files do not exist: " + srcFile.getAbsolutePath()); + } + if(excludes!=null && excludes.length>0){ + for (int i=0; i0){ + for(String exclude : excludes){ + if(exclude.equalsIgnoreCase(srcFile.getCanonicalPath())){ + return; + } + } + } + + if (srcFile.isDirectory()) { + File[] files = srcFile.listFiles(); + base = base.length() == 0 ? "" : base + "/"; + if (base.length() > 0) { + out.putNextEntry(new ZipEntry(base)); + /* ZipEntry zipEntry = new ZipEntry(base); + zipEntry.setUnixMode(755);// 解决linux乱码 + out.putNextEntry(zipEntry);*/ + } + for (int i = 0; i < files.length; i++) { + zip(out, files[i], base + files[i].getName(), excludes); + } + } else { + base = base.length() == 0 ? srcFile.getName() : base; + out.putNextEntry(new ZipEntry(base)); + /*ZipEntry zipEntry=new ZipEntry(base); + zipEntry.setUnixMode(644);//解决linux乱码 + out.putNextEntry(zipEntry);*/ + FileInputStream fis = null; + try{ + fis = new FileInputStream(srcFile); + IOUtils.copy(fis, out); + }catch (IOException e) { + throw e; + }finally{ + if(fis!=null) fis.close(); + } + } + out.closeEntry(); + } + + /** + * 将单个文件或一个目录打成zip包,并将原文件删除 + * + * @param srcFiles 需要压压缩的文件列表 + * @param destFile 压缩后的目标文件 + * @param isAddPrefix 是否要添加文件前缀 + * @throws Exception + */ + public static void zipWithDelFile(File[] srcFiles, String destFile, boolean isAddPrefix) throws Exception { + logger.debug("pass ZipUtil zipWithDelFile(File[] srcFiles, String destFile, boolean isAddPrefix):"); + if(srcFiles!=null){ + logger.debug("ZipUtil zipWithDelFile(File[] srcFiles, String destFile, boolean isAddPrefix) srcFiles:"+srcFiles.length); + } + ZipOutputStream out = null; + try{ + out = new ZipOutputStream(new FileOutputStream(destFile)); + //out.setEncoding("GBK");//解决linux乱码 + if (srcFiles==null || srcFiles.length==0) { +// throw new Exception("压缩文件列表为空"); + throw new Exception("The list of compressed files is empty"); + } + for(File file : srcFiles){ + zip(out,file,"", true, isAddPrefix, null); + } + }catch (Exception e) { + throw e; + }finally { + if(out!=null) out.close(); + } + } + + /** + * 将单个文件或一个目录打成zip包,并将原文件删除或移动 + * + * @param srcFiles 需要压压缩的文件列表 + * @param destFile 压缩后的目标文件 + * @param isAddPrefix 是否要添加文件前缀 + * @throws Exception + */ + public static void zipWithMoveFile(File[] srcFiles, String destFile, boolean isAddPrefix) throws Exception { + ZipOutputStream out = null; + try{ + out = new ZipOutputStream(new FileOutputStream(destFile)); + //out.setEncoding("GBK");//解决linux乱码 + if (srcFiles==null || srcFiles.length==0) { +// throw new Exception("压缩文件列表为空"); + throw new Exception("The list of compressed files is empty"); + } + // 2013-03-22 由于DC再次获取未保存任务结果这个功能的实现,现修改将任务结果和回传文件压缩时不删除文件,而是将其移动到相应的日期目录 + String dataType = null; + String destFileName = new File(destFile).getName(); + if(destFileName.startsWith(CommonSocket.BP_TYPE_TASK_RESULT)){ + dataType = CommonSocket.BP_TYPE_TASK_RESULT; + }else if(destFileName.startsWith(CommonSocket.BP_TYPE_TASK_RETURN)){ + dataType = CommonSocket.BP_TYPE_TASK_RETURN; + }else if(destFileName.startsWith(CommonSocket.BP_TYPE_DETECT_DATA)){ + dataType = CommonSocket.BP_TYPE_DETECT_DATA; + } + logger.debug("zipWithMoveFile --- dataType = " + dataType); + for(File file : srcFiles){ + // 2013-5-6 针对监测数据打包文件个数的限制,即srcFiles传来的是一定个数的文件,不是所有监测的目录,所以压缩文件中的文件名要加上文件的父目录名 + if(CommonSocket.BP_TYPE_DETECT_DATA.equalsIgnoreCase(dataType) && file.isFile()){ + zip(out, file, file.getParentFile().getName() + "_" + file.getName(), true, isAddPrefix, dataType); + }else{ + zip(out,file,"", true, isAddPrefix, dataType); + } + } + }catch (Exception e) { + throw e; + }finally { + if(out!=null) out.close(); + } + } + + /** + * zip压缩 + * @param out: Zip压缩流 + * @param srcFile: 要压缩的文件或目录 + * @param base: 要压缩文件在zip包内的路径 + * @param isDel 是否删除压缩的文件, 若dataType为null,则直接删除,若dataType不为null, 则移动到指定目录 + * @param isAddPrefix 是否要添加文件前缀,true 如果是文件则将父文件夹的名称加到文件名的前缀,作为压缩后的文件名 + * @throws Exception + */ + protected static void zip(ZipOutputStream out, File srcFile, String base, boolean isDel, boolean isAddPrefix, String dataType) throws Exception{ + if (!srcFile.exists()) { +// throw new Exception("压缩目录或文件不存在: " + srcFile.getAbsolutePath()); + throw new Exception("Compressed directories or files do not exist: " + srcFile.getAbsolutePath()); + } + logger.debug("pass ZipUtil zip"); + + if (srcFile.isDirectory()) { + File[] files = srcFile.listFiles(); + base = base.length() == 0 ? "" : base + "/"; + if (base.length() > 0) { + out.putNextEntry(new ZipEntry(base)); + /* ZipEntry zipEntry = new ZipEntry(base); + zipEntry.setUnixMode(755);// 解决linux乱码 + out.putNextEntry(zipEntry);*/ + } + for (int i = 0; i < files.length; i++) { + String fileName = files[i].getName(); + if(isAddPrefix){ + fileName = files[i].getParentFile().getName() + "_" + files[i].getName(); + } + zip(out, files[i], base + fileName, isDel, isAddPrefix, dataType); + } + } else{ + base = base.length() == 0 ? srcFile.getName() : base; + out.putNextEntry(new ZipEntry(base)); + /*ZipEntry zipEntry=new ZipEntry(base); + zipEntry.setUnixMode(644);//解决linux乱码 + out.putNextEntry(zipEntry);*/ + FileInputStream fis = null; + try{ + fis = new FileInputStream(srcFile); + IOUtils.copy(fis, out); + }catch (IOException e) { + throw e; + }finally{ + if(fis!=null) fis.close(); + } + if(srcFile.exists() && isDel){ + // 2013-03-22 由于DC再次获取未保存任务结果这个功能的实现,现修改将任务结果和回传文件压缩时不删除文件,而是将其移动到相应的日期目录 + if(CommonSocket.BP_TYPE_TASK_RESULT.equalsIgnoreCase(dataType)){ + ServerCollectData.moveTaskResultToDateDir(srcFile); + }else if(CommonSocket.BP_TYPE_TASK_RETURN.equalsIgnoreCase(dataType)){ + ServerCollectData.moveTaskReturnToDateDir(srcFile, null); + }else if(CommonSocket.BP_TYPE_DETECT_DATA.equalsIgnoreCase(dataType)){ + ServerCollectData.moveDetecDataToDateDir(srcFile); + }else { + FileUtil.delDir(srcFile); + logger.debug("ZipUtil.zip()----delete srcFile=" + srcFile.getAbsolutePath()); + } + } + } + out.closeEntry(); + } + + public static void main(String[] args) { + try { + File f = new File("D:/work/create_tablespace"); + System.out.println(f.getPath()); + long tt = System.currentTimeMillis(); + /*String[] excludes = new String[3]; + excludes[0] = "D:\\temp\\t1\\test\\src"; + excludes[1] = "D:\\temp\\t1\\test\\WebRoot\\WEB-INF\\lib\\jdom.jar"; + excludes[2] = "D:\\temp\\t1\\test\\ziptest_code.zip"; + ZipUtil.zip("D:\\temp\\t1", "D:\\temp\\test\\t1.zip", excludes); + //ZipUtil.unZip("D:\\temp\\test\\ziptest_code.zip", "D:\\temp"); + System.out.println(System.currentTimeMillis()-tt);*/ + ZipUtil.zipWithDelFile(new File("D:\\nmstest\\logs\\").listFiles(), "D:\\test\\nmsserver.log.zip", true); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/src/com/nis/nmsclient/util/file/BufferedRandomAccessFile.java b/src/com/nis/nmsclient/util/file/BufferedRandomAccessFile.java new file mode 100644 index 0000000..ca78182 --- /dev/null +++ b/src/com/nis/nmsclient/util/file/BufferedRandomAccessFile.java @@ -0,0 +1,313 @@ +package com.nis.nmsclient.util.file; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.ResourceBundle; + +/** + *

Title: BufferedRandomAccessFile

+ *

Description: this class provide Buffered Read & Write by extend RandomAccessFile

+ *

Copyright: Copyright (c) 2002 Cui Zhixiang

+ *

Company: soho

+ * @author Cui Zhixiang + * @version 1.0, 2002/10/12 + */ + +public class BufferedRandomAccessFile extends RandomAccessFile { + + static ResourceBundle res = ResourceBundle.getBundle(Res.class.getName()); + private static final int DEFAULT_BUFFER_BIT_LEN = 10; + private static final int DEFAULT_BUFFER_SIZE = 1 << DEFAULT_BUFFER_BIT_LEN; + + protected byte buf[]; + protected int bufbitlen; + protected int bufsize; + protected long bufmask; + protected boolean bufdirty; + protected int bufusedsize; + protected long curpos; + + protected long bufstartpos; + protected long bufendpos; + protected long fileendpos; + + protected boolean append; + protected String filename; + protected long initfilelen; + + public BufferedRandomAccessFile(String name) throws IOException { + this(name, res.getString("r"), DEFAULT_BUFFER_BIT_LEN); + } + + public BufferedRandomAccessFile(File file) throws IOException, FileNotFoundException { + this(file.getPath(), res.getString("r"), DEFAULT_BUFFER_BIT_LEN); + } + + public BufferedRandomAccessFile(String name, int bufbitlen) throws IOException { + this(name, res.getString("r"), bufbitlen); + } + + public BufferedRandomAccessFile(File file, int bufbitlen) throws IOException, FileNotFoundException { + this(file.getPath(), res.getString("r"), bufbitlen); + } + + public BufferedRandomAccessFile(String name, String mode) throws IOException { + this(name, mode, DEFAULT_BUFFER_BIT_LEN); + } + + public BufferedRandomAccessFile(File file, String mode) throws IOException, FileNotFoundException { + this(file.getPath(), mode, DEFAULT_BUFFER_BIT_LEN); + } + + public BufferedRandomAccessFile(String name, String mode, int bufbitlen) throws IOException { + super(name, mode); + this.init(name, mode, bufbitlen); + } + + public BufferedRandomAccessFile(File file, String mode, int bufbitlen) throws IOException, FileNotFoundException { + this(file.getPath(), mode, bufbitlen); + } + + private void init(String name, String mode, int bufbitlen) throws IOException { + if (mode.equals(res.getString("r")) == true) { + this.append = false; + } else { + this.append = true; + } + + this.filename = name; + this.initfilelen = super.length(); + this.fileendpos = this.initfilelen - 1; + this.curpos = super.getFilePointer(); + + if (bufbitlen < 0) { + throw new IllegalArgumentException(res.getString("bufbitlen_size_must_0")); + } + + this.bufbitlen = bufbitlen; + this.bufsize = 1 << bufbitlen; + this.buf = new byte[this.bufsize]; + this.bufmask = ~((long)this.bufsize - 1L); + this.bufdirty = false; + this.bufusedsize = 0; + this.bufstartpos = -1; + this.bufendpos = -1; + } + + private void flushbuf() throws IOException { + if (this.bufdirty == true) { + if (super.getFilePointer() != this.bufstartpos) { + super.seek(this.bufstartpos); + } + super.write(this.buf, 0, this.bufusedsize); + this.bufdirty = false; + } + } + + private int fillbuf() throws IOException { + super.seek(this.bufstartpos); + this.bufdirty = false; + return super.read(this.buf); + } + + public byte read(long pos) throws IOException { + if (pos < this.bufstartpos || pos > this.bufendpos) { + this.flushbuf(); + this.seek(pos); + + if ((pos < this.bufstartpos) || (pos > this.bufendpos)) { + throw new IOException(); + } + } + this.curpos = pos; + return this.buf[(int)(pos - this.bufstartpos)]; + } + + public boolean write(byte bw) throws IOException { + return this.write(bw, this.curpos); + } + + public boolean append(byte bw) throws IOException { + return this.write(bw, this.fileendpos + 1); + } + + public boolean write(byte bw, long pos) throws IOException { + + if ((pos >= this.bufstartpos) && (pos <= this.bufendpos)) { // write pos in buf + this.buf[(int)(pos - this.bufstartpos)] = bw; + this.bufdirty = true; + + if (pos == this.fileendpos + 1) { // write pos is append pos + this.fileendpos++; + this.bufusedsize++; + } + } else { // write pos not in buf + this.seek(pos); + + if ((pos >= 0) && (pos <= this.fileendpos) && (this.fileendpos != 0)) { // write pos is modify file + this.buf[(int)(pos - this.bufstartpos)] = bw; + + } else if (((pos == 0) && (this.fileendpos == 0)) || (pos == this.fileendpos + 1)) { // write pos is append pos + this.buf[0] = bw; + this.fileendpos++; + this.bufusedsize = 1; + } else { + throw new IndexOutOfBoundsException(); + } + this.bufdirty = true; + } + this.curpos = pos; + return true; + } + + public void write(byte b[], int off, int len) throws IOException { + + long writeendpos = this.curpos + len - 1; + + if (writeendpos <= this.bufendpos) { // b[] in cur buf + System.arraycopy(b, off, this.buf, (int)(this.curpos - this.bufstartpos), len); + this.bufdirty = true; + this.bufusedsize = (int)(writeendpos - this.bufstartpos + 1);//(int)(this.curpos - this.bufstartpos + len - 1); + + } else { // b[] not in cur buf + super.seek(this.curpos); + super.write(b, off, len); + } + + if (writeendpos > this.fileendpos) + this.fileendpos = writeendpos; + + this.seek(writeendpos+1); + } + + public int read(byte b[], int off, int len) throws IOException { + + long readendpos = this.curpos + len - 1; + + if (readendpos <= this.bufendpos && readendpos <= this.fileendpos ) { // read in buf + System.arraycopy(this.buf, (int)(this.curpos - this.bufstartpos), b, off, len); + } else { // read b[] size > buf[] + + if (readendpos > this.fileendpos) { // read b[] part in file + len = (int)(this.length() - this.curpos + 1); + } + + super.seek(this.curpos); + len = super.read(b, off, len); + readendpos = this.curpos + len - 1; + } + this.seek(readendpos + 1); + return len; + } + + public void write(byte b[]) throws IOException { + this.write(b, 0, b.length); + } + + public int read(byte b[]) throws IOException { + return this.read(b, 0, b.length); + } + + public void seek(long pos) throws IOException { + + if ((pos < this.bufstartpos) || (pos > this.bufendpos)) { // seek pos not in buf + this.flushbuf(); + + if ((pos >= 0) && (pos <= this.fileendpos) && (this.fileendpos != 0)) { // seek pos in file (file length > 0) + this.bufstartpos = pos & this.bufmask; + this.bufusedsize = this.fillbuf(); + + } else if (((pos == 0) && (this.fileendpos == 0)) || (pos == this.fileendpos + 1)) { // seek pos is append pos + + this.bufstartpos = pos; + this.bufusedsize = 0; + } + this.bufendpos = this.bufstartpos + this.bufsize - 1; + } + this.curpos = pos; + } + + public long length() throws IOException { + return this.max(this.fileendpos + 1, this.initfilelen); + } + + public void setLength(long newLength) throws IOException { + if (newLength > 0) { + this.fileendpos = newLength - 1; + } else { + this.fileendpos = 0; + } + super.setLength(newLength); + } + public long getFilePointer() throws IOException { + return this.curpos; + } + + private long max(long a, long b) { + if (a > b) return a; + return b; + } + + public void close() throws IOException { + this.flushbuf(); + super.close(); + } + + public static void main(String[] args) throws IOException { + long readfilelen = 0; + BufferedRandomAccessFile brafReadFile, brafWriteFile; + + brafReadFile = new BufferedRandomAccessFile("C:\\WINNT\\Fonts\\STKAITI.TTF"); + readfilelen = brafReadFile.initfilelen; + brafWriteFile = new BufferedRandomAccessFile(".\\STKAITI.001", "rw", 10); + + byte buf[] = new byte[1024]; + int readcount; + + long start = System.currentTimeMillis(); + + while((readcount = brafReadFile.read(buf)) != -1) { + brafWriteFile.write(buf, 0, readcount); + } + + brafWriteFile.close(); + brafReadFile.close(); + + System.out.println("BufferedRandomAccessFile Copy & Write File: " + + brafReadFile.filename + + " FileSize: " + + java.lang.Integer.toString((int)readfilelen >> 1024) + + " (KB) " + + "Spend: " + +(double)(System.currentTimeMillis()-start) / 1000 + + "(s)"); + + java.io.FileInputStream fdin = new java.io.FileInputStream("C:\\WINNT\\Fonts\\STKAITI.TTF"); + java.io.BufferedInputStream bis = new java.io.BufferedInputStream(fdin, 1024); + java.io.DataInputStream dis = new java.io.DataInputStream(bis); + + java.io.FileOutputStream fdout = new java.io.FileOutputStream(".\\STKAITI.002"); + java.io.BufferedOutputStream bos = new java.io.BufferedOutputStream(fdout, 1024); + java.io.DataOutputStream dos = new java.io.DataOutputStream(bos); + + start = System.currentTimeMillis(); + + for (int i = 0; i < readfilelen; i++) { + dos.write(dis.readByte()); + } + + dos.close(); + dis.close(); + + System.out.println("DataBufferedios Copy & Write File: " + + brafReadFile.filename + + " FileSize: " + + java.lang.Integer.toString((int)readfilelen >> 1024) + + " (KB) " + + "Spend: " + + (double)(System.currentTimeMillis()-start) / 1000 + + "(s)"); + } +} diff --git a/src/com/nis/nmsclient/util/file/Res.java b/src/com/nis/nmsclient/util/file/Res.java new file mode 100644 index 0000000..7e61830 --- /dev/null +++ b/src/com/nis/nmsclient/util/file/Res.java @@ -0,0 +1,17 @@ +package com.nis.nmsclient.util.file; + +public class Res extends java.util.ListResourceBundle { + static final Object[][] contents = new String[][]{ + { "r", "r" }, + { "bufbitlen_size_must_0", "bufbitlen size must >= 0" }, + { "rw", "rw" }, + { "BufferedRandomAccess", "BufferedRandomAccessFile Copy & Write File: " }, + { "FileSize_", " FileSize: " }, + { "_KB_", " (KB) " }, + { "Spend_", "Spend: " }, + { "_s_", "(s)" }, + { "DataBufferedios_Copy", "DataBufferedios Copy & Write File: " }}; + public Object[][] getContents() { + return contents; + } +} \ No newline at end of file diff --git a/src/com/nis/nmsclient/util/io/UnicodeInputStream.java b/src/com/nis/nmsclient/util/io/UnicodeInputStream.java new file mode 100644 index 0000000..9e61d42 --- /dev/null +++ b/src/com/nis/nmsclient/util/io/UnicodeInputStream.java @@ -0,0 +1,118 @@ +package com.nis.nmsclient.util.io; +/** + version: 1.1 / 2007-01-25 + - changed BOM recognition ordering (longer boms first) + + Original pseudocode : Thomas Weidenfeller + Implementation tweaked: Aki Nieminen + + http://www.unicode.org/unicode/faq/utf_bom.html + BOMs in byte length ordering: + 00 00 FE FF = UTF-32, big-endian + FF FE 00 00 = UTF-32, little-endian + EF BB BF = UTF-8, + FE FF = UTF-16, big-endian + FF FE = UTF-16, little-endian + + Win2k Notepad: + Unicode format = UTF-16LE + ***/ + +import java.io.*; + +/** + * This inputstream will recognize unicode BOM marks and will skip bytes if + * getEncoding() method is called before any of the read(...) methods. + * + * Usage pattern: String enc = "ISO-8859-1"; // or NULL to use systemdefault + * FileInputStream fis = new FileInputStream(file); UnicodeInputStream uin = new + * UnicodeInputStream(fis, enc); enc = uin.getEncoding(); // check and skip + * possible BOM bytes InputStreamReader in; if (enc == null) in = new + * InputStreamReader(uin); else in = new InputStreamReader(uin, enc); + */ +public class UnicodeInputStream extends InputStream { + PushbackInputStream internalIn; + boolean isInited = false; + String defaultEnc; + String encoding; + + private static final int BOM_SIZE = 4; + + UnicodeInputStream(InputStream in, String defaultEnc) { + internalIn = new PushbackInputStream(in, BOM_SIZE); + this.defaultEnc = defaultEnc; + } + + public String getDefaultEncoding() { + return defaultEnc; + } + + public String getEncoding() { + if (!isInited) { + try { + init(); + } catch (IOException ex) { + IllegalStateException ise = new IllegalStateException( + "Init method failed."); + ise.initCause(ise); + throw ise; + } + } + return encoding; + } + + /** + * Read-ahead four bytes and check for BOM marks. Extra bytes are unread + * back to the stream, only BOM bytes are skipped. + */ + protected void init() throws IOException { + if (isInited) + return; + + byte bom[] = new byte[BOM_SIZE]; + int n, unread; + n = internalIn.read(bom, 0, bom.length); + + if ((bom[0] == (byte) 0x00) && (bom[1] == (byte) 0x00) + && (bom[2] == (byte) 0xFE) && (bom[3] == (byte) 0xFF)) { + encoding = "UTF-32BE"; + unread = n - 4; + } else if ((bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE) + && (bom[2] == (byte) 0x00) && (bom[3] == (byte) 0x00)) { + encoding = "UTF-32LE"; + unread = n - 4; + } else if ((bom[0] == (byte) 0xEF) && (bom[1] == (byte) 0xBB) + && (bom[2] == (byte) 0xBF)) { + encoding = "UTF-8"; + unread = n - 3; + } else if ((bom[0] == (byte) 0xFE) && (bom[1] == (byte) 0xFF)) { + encoding = "UTF-16BE"; + unread = n - 2; + } else if ((bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE)) { + encoding = "UTF-16LE"; + unread = n - 2; + } else { + // Unicode BOM mark not found, unread all bytes + encoding = defaultEnc; + unread = n; + } + // System.out.println("read=" + n + ", unread=" + unread); + + if (unread > 0) + internalIn.unread(bom, (n - unread), unread); + + isInited = true; + } + + public void close() throws IOException { + // init(); + isInited = true; + internalIn.close(); + } + + public int read() throws IOException { + // init(); + isInited = true; + return internalIn.read(); + } +} diff --git a/src/com/nis/nmsclient/util/io/UnicodeReader.java b/src/com/nis/nmsclient/util/io/UnicodeReader.java new file mode 100644 index 0000000..c4169b5 --- /dev/null +++ b/src/com/nis/nmsclient/util/io/UnicodeReader.java @@ -0,0 +1,120 @@ +package com.nis.nmsclient.util.io; +/** + version: 1.1 / 2007-01-25 + - changed BOM recognition ordering (longer boms first) + + Original pseudocode : Thomas Weidenfeller + Implementation tweaked: Aki Nieminen + + http://www.unicode.org/unicode/faq/utf_bom.html + BOMs: + 00 00 FE FF = UTF-32, big-endian + FF FE 00 00 = UTF-32, little-endian + EF BB BF = UTF-8, + FE FF = UTF-16, big-endian + FF FE = UTF-16, little-endian + + Win2k Notepad: + Unicode format = UTF-16LE + ***/ + +import java.io.*; + +/** + * Generic unicode textreader, which will use BOM mark to identify the encoding + * to be used. If BOM is not found then use a given default or system encoding. + */ +public class UnicodeReader extends Reader { + PushbackInputStream internalIn; + InputStreamReader internalIn2 = null; + String defaultEnc; + + private static final int BOM_SIZE = 4; + + /** + * + * @param in + * inputstream to be read + * @param defaultEnc + * default encoding if stream does not have BOM marker. Give NULL + * to use system-level default. + */ + public UnicodeReader(InputStream in, String defaultEnc) { + internalIn = new PushbackInputStream(in, BOM_SIZE); + this.defaultEnc = defaultEnc; + } + + public String getDefaultEncoding() { + return defaultEnc; + } + + /** + * Get stream encoding or NULL if stream is uninitialized. Call init() or + * read() method to initialize it. + */ + public String getEncoding() { + if (internalIn2 == null) + return null; + return internalIn2.getEncoding(); + } + + /** + * Read-ahead four bytes and check for BOM marks. Extra bytes are unread + * back to the stream, only BOM bytes are skipped. + */ + protected void init() throws IOException { + if (internalIn2 != null) + return; + + String encoding; + byte bom[] = new byte[BOM_SIZE]; + int n, unread; + n = internalIn.read(bom, 0, bom.length); + + if ((bom[0] == (byte) 0x00) && (bom[1] == (byte) 0x00) + && (bom[2] == (byte) 0xFE) && (bom[3] == (byte) 0xFF)) { + encoding = "UTF-32BE"; + unread = n - 4; + } else if ((bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE) + && (bom[2] == (byte) 0x00) && (bom[3] == (byte) 0x00)) { + encoding = "UTF-32LE"; + unread = n - 4; + } else if ((bom[0] == (byte) 0xEF) && (bom[1] == (byte) 0xBB) + && (bom[2] == (byte) 0xBF)) { + encoding = "UTF-8"; + unread = n - 3; + } else if ((bom[0] == (byte) 0xFE) && (bom[1] == (byte) 0xFF)) { + encoding = "UTF-16BE"; + unread = n - 2; + } else if ((bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE)) { + encoding = "UTF-16LE"; + unread = n - 2; + } else { + // Unicode BOM mark not found, unread all bytes + encoding = defaultEnc; + unread = n; + } + // System.out.println("read=" + n + ", unread=" + unread); + + if (unread > 0) + internalIn.unread(bom, (n - unread), unread); + + // Use given encoding + if (encoding == null) { + internalIn2 = new InputStreamReader(internalIn); + } else { + internalIn2 = new InputStreamReader(internalIn, encoding); + } + } + + public void close() throws IOException { + init(); + internalIn2.close(); + } + + public int read(char[] cbuf, int off, int len) throws IOException { + init(); + return internalIn2.read(cbuf, off, len); + } + +} \ No newline at end of file diff --git a/src/com/nis/nmsclient/util/log4j/MyDailyRollingFileAppender.java b/src/com/nis/nmsclient/util/log4j/MyDailyRollingFileAppender.java new file mode 100644 index 0000000..b003cc4 --- /dev/null +++ b/src/com/nis/nmsclient/util/log4j/MyDailyRollingFileAppender.java @@ -0,0 +1,14 @@ +package com.nis.nmsclient.util.log4j; + +import org.apache.log4j.DailyRollingFileAppender; +import org.apache.log4j.Priority; + +public class MyDailyRollingFileAppender extends DailyRollingFileAppender { + + @Override + public boolean isAsSevereAsThreshold(Priority priority) { + // 只判断相等,不判断优先级 + return this.getThreshold().equals(priority); + } + +} diff --git a/src/com/nis/nmsclient/util/log4j/MyRollingFileAppender.java b/src/com/nis/nmsclient/util/log4j/MyRollingFileAppender.java new file mode 100644 index 0000000..133c592 --- /dev/null +++ b/src/com/nis/nmsclient/util/log4j/MyRollingFileAppender.java @@ -0,0 +1,14 @@ +package com.nis.nmsclient.util.log4j; + +import org.apache.log4j.Priority; +import org.apache.log4j.RollingFileAppender; + +public class MyRollingFileAppender extends RollingFileAppender { + + @Override + public boolean isAsSevereAsThreshold(Priority priority) { + // 只判断相等,不判断优先级 + return this.getThreshold().equals(priority); + } + +} diff --git a/src/com/nis/systeminfo/model/DetectInfo.java b/src/com/nis/systeminfo/model/DetectInfo.java new file mode 100644 index 0000000..8ffd12f --- /dev/null +++ b/src/com/nis/systeminfo/model/DetectInfo.java @@ -0,0 +1,49 @@ +package com.nis.systeminfo.model; + +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +public class DetectInfo { + /* + * 该字段是针对,同一时间点多条具体数据(写多个文件),比如:网卡监测(多个网卡问题) + */ + private List detailDatas = new LinkedList(); + /* + * 针对公共数据的描述信息 + */ + private String descInfo; + /* + * 该字段是针对一条数据,关联的其他表的数据;写入到一个文件的: String 是解析标识, List是多条数据(String[]存入表中的数据) + * 如:系统信息监测,数据中有网卡数量,网卡数量关联着其他表(表中又有多个字段,如网卡名称,IP,子网掩码等等) + */ + private Map> relatedDatas; + + private String diskMsg;//用于存储硬盘只读和磁盘满的异常信息 + + public List getDetailDatas() { + return detailDatas; + } + public void setDetailDatas(List detailDatas) { + this.detailDatas = detailDatas; + } + public String getDescInfo() { + return descInfo; + } + public void setDescInfo(String descInfo) { + this.descInfo = descInfo; + } + public Map> getRelatedDatas() { + return relatedDatas; + } + public void setRelatedDatas(Map> relatedDatas) { + this.relatedDatas = relatedDatas; + } + public String getDiskMsg() { + return diskMsg; + } + public void setDiskMsg(String diskMsg) { + this.diskMsg = diskMsg; + } + +} diff --git a/src/com/nis/systeminfo/model/SystemInfo.java b/src/com/nis/systeminfo/model/SystemInfo.java new file mode 100644 index 0000000..0a2d42f --- /dev/null +++ b/src/com/nis/systeminfo/model/SystemInfo.java @@ -0,0 +1,1029 @@ +package com.nis.systeminfo.model; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import org.apache.log4j.Logger; +import org.hyperic.sigar.Cpu; +import org.hyperic.sigar.CpuInfo; +import org.hyperic.sigar.CpuPerc; +import org.hyperic.sigar.FileSystem; +import org.hyperic.sigar.FileSystemUsage; +import org.hyperic.sigar.Mem; +import org.hyperic.sigar.NetFlags; +import org.hyperic.sigar.NetInterfaceConfig; +import org.hyperic.sigar.NetInterfaceStat; +import org.hyperic.sigar.ProcCpu; +import org.hyperic.sigar.ProcState; +import org.hyperic.sigar.Sigar; +import org.hyperic.sigar.SigarException; +import org.hyperic.sigar.Swap; +import org.hyperic.sigar.Uptime; +import org.hyperic.sigar.cmd.Ps; +import com.nis.nmsclient.common.Common; +import com.nis.nmsclient.common.Contants; +import com.nis.nmsclient.thread.socket.CommonSocket; +import com.nis.nmsclient.thread.socket.SSLClient; +import com.nis.nmsclient.util.DateUtil; +import com.nis.nmsclient.util.ProcessUtil; +import com.nis.nmsclient.util.Utils; + +public class SystemInfo +{ + + static Logger logger = Logger.getLogger(SystemInfo.class); + + public static String SEPARATOR = "@#@"; + + private Thread thread = null;// 这个属性是取进程信息中启动进程时使用 + + public DetectInfo getDetectInfo(String checkType, String pidFile, String processPath, + String procSearchKey, boolean isStart) + { + DetectInfo detectInfo = null; + if (checkType != null) + { + if (checkType.equalsIgnoreCase(Contants.SYS_CHECK_TYPE_CPU)) + {// CPU + detectInfo = testCpuPerc(); + } else if (checkType.equalsIgnoreCase(Contants.SYS_CHECK_TYPE_MEMORY)) + {// 内存 + detectInfo = testPhysicalMemory(); + } else if (checkType.equalsIgnoreCase(Contants.SYS_CHECK_TYPE_DISK)) + {// 硬盘 + detectInfo = testFileSystemInfo(); + } else if (checkType.equalsIgnoreCase(Contants.SYS_CHECK_TYPE_NET)) + {// 网络流量 + detectInfo = testNetDataList(); + } else if (checkType.equalsIgnoreCase(Contants.SYS_CHECK_TYPE_SYSDATE)) + {// 系统时间 + detectInfo = testSystemDate(); + } else if (checkType.equalsIgnoreCase(Contants.SYS_CHECK_TYPE_PROCESS)) + {// 进程信息 + detectInfo = testProcessInfo(pidFile, processPath, procSearchKey, isStart); + } else if (checkType.equalsIgnoreCase(Contants.SYS_CHECK_TYPE_SYSTEMINFO)) + {// 系统信息 + detectInfo = testSystemInfo(); + } + } + + return detectInfo; + } + + // CPU的用户使用量、系统使用剩余量、总的剩余量、总的使用占用量等(单位:100%) + public DetectInfo testCpuPerc() + { + DetectInfo detectInfo = new DetectInfo(); + try + { + Sigar sigar = new Sigar(); + // 不管是单块CPU还是多CPU都适用 + CpuPerc cpuList[] = sigar.getCpuPercList(); + CpuInfo[] cpuInfos = sigar.getCpuInfoList(); +// StringBuffer sb2 = new StringBuffer(cpuList.length + "核: "); + StringBuffer sb2 = new StringBuffer(); + double userCpuPerc = 0.0; + double sysCpuPerc = 0.0; + double waitCpuPerc = 0.0; + double niceCpuPerc = 0.0; + double idleCpuPerc = 0.0; + double totalCpuPerc = 0.0; + long mhzCpuPerc = 0; + for (int i = 0; i < cpuList.length; i++) + { + StringBuffer sb = new StringBuffer(); + sb.append("cpu" + i);// 标识 + sb.append(SEPARATOR); + sb.append(CpuPerc.format(cpuList[i].getUser()));// 用户使用率:CPU耗费在不正常的用户进程的使用率 + sb.append(SEPARATOR); + sb.append(CpuPerc.format(cpuList[i].getSys()));// 系统使用率 + sb.append(SEPARATOR); + sb.append(CpuPerc.format(cpuList[i].getWait()));// 当前等待率 + sb.append(SEPARATOR); + sb.append(CpuPerc.format(cpuList[i].getNice()));// 用户使用率:正常的用户进程的CPU使用率 + sb.append(SEPARATOR); + sb.append(CpuPerc.format(cpuList[i].getIdle()));// 当前空闲率 + sb.append(SEPARATOR); + sb.append(CpuPerc.format(cpuList[i].getCombined()));// 总的使用率 + sb.append(SEPARATOR); + sb.append(cpuInfos[i].getMhz());// 主频 + detectInfo.getDetailDatas().add(sb.toString().replace("%", "")); +// sb2.append(Contants.DETEC_STATE_INFO_FORMATE_POINT+"cpu" + i + " 主频" + cpuInfos[i].getMhz() + "MHz,使用率 " + sb2.append(Contants.DETEC_STATE_INFO_FORMATE_POINT+"cpu" + i + " i18n_client.SystemInfo.mhz_n81i" + cpuInfos[i].getMhz() + "MHz,i18n_client.SystemInfo.shiyonglv_n81i " + + CpuPerc.format(cpuList[i].getCombined()) + "; "); + + // CPU总体信息情况 + userCpuPerc += cpuList[i].getUser();// 用户使用率累加 + sysCpuPerc += cpuList[i].getSys();// 系统使用率 + waitCpuPerc += cpuList[i].getWait();// 当前等待率 + niceCpuPerc += cpuList[i].getNice();// 用户使用率:正常的用户进程的CPU使用率 + idleCpuPerc += cpuList[i].getIdle();// 当前空闲率 + totalCpuPerc += cpuList[i].getCombined();// 总的使用率 + mhzCpuPerc = cpuInfos[i].getMhz();// 主频 + } + + StringBuffer sb = new StringBuffer(); + sb.append("cpu");// 标识 + sb.append(SEPARATOR); + sb.append(CpuPerc.format(userCpuPerc/cpuList.length));// 用户使用率:CPU耗费在不正常的用户进程的使用率 + sb.append(SEPARATOR); + sb.append(CpuPerc.format(sysCpuPerc/cpuList.length));// 系统使用率 + sb.append(SEPARATOR); + sb.append(CpuPerc.format(waitCpuPerc/cpuList.length));// 当前等待率 + sb.append(SEPARATOR); + sb.append(CpuPerc.format(niceCpuPerc/cpuList.length));// 用户使用率:正常的用户进程的CPU使用率 + sb.append(SEPARATOR); + sb.append(CpuPerc.format(idleCpuPerc/cpuList.length));// 当前空闲率 + sb.append(SEPARATOR); + sb.append(CpuPerc.format(totalCpuPerc/cpuList.length));// 总的使用率 + sb.append(SEPARATOR); + sb.append(mhzCpuPerc);// 主频 + detectInfo.getDetailDatas().add(sb.toString().replace("%", "")); +// sb2.append(Contants.DETEC_STATE_INFO_FORMATE_POINT+"cpu" + " 主频" +mhzCpuPerc + "MHz,使用率 " + CpuPerc.format(totalCpuPerc/cpuList.length) + "; "); +// sb2.insert(0,cpuList.length + "核: "+Contants.DETEC_STATE_INFO_FORMATE_POINT+"cpu" + " 主频" +mhzCpuPerc + "MHz,使用率 " + CpuPerc.format(totalCpuPerc/cpuList.length) + "; "); + sb2.insert(0,cpuList.length + "i18n_client.SystemInfo.core_n81i: "+Contants.DETEC_STATE_INFO_FORMATE_POINT+"cpu" + "i18n_client.SystemInfo.mhz_n81i" +mhzCpuPerc + "MHz,i18n_client.SystemInfo.shiyonglv_n81i " + CpuPerc.format(totalCpuPerc/cpuList.length) + "; "); + + detectInfo.setDescInfo(sb2.toString()); + logger.debug("testCpuPerc---" + sb2.toString()); + } catch (Exception e) + { + logger.error("Getting CPU information exception", e); + return null; + } + + return detectInfo; + } + + // 内存资源信息 + public DetectInfo testPhysicalMemory() + { + DetectInfo detectInfo = new DetectInfo(); + try + { + Sigar sigar = new Sigar(); + + StringBuffer sb = new StringBuffer(); + // b)系统页面文件交换区信息 + Swap swap = sigar.getSwap(); + Long swapTotal = swap.getTotal(); // 交换区总量 + Long swapFree = swap.getFree();// 当前交换区剩余量 + sb.append(doubleFormat(swapTotal / (1024 * 1024 * 1024.0), 2));// 交换区总量,单位:"G" + sb.append(SEPARATOR); + sb.append(doubleFormat(swapFree / (1024 * 1024 * 1024.0), 2));// 当前交换区剩余量,单位:"G" + sb.append(SEPARATOR); + // sb.append(SEPARATOR); + // sb.append(swap.getUsed() / 1024L);// 当前交换区使用量,单位:"K" + // a)物理内存信息 + Mem mem = sigar.getMem(); + Long memTotal = mem.getTotal();// 内存总量 + Long memUsed = mem.getUsed();// 当前内存使用量 + Long memFree = mem.getFree();// 当前内存剩余量 + sb.append(doubleFormat(memTotal / (1024 * 1024 * 1024.0), 2));// 内存总量,单位:"G" + sb.append(SEPARATOR); + sb.append(doubleFormat(memUsed / (1024 * 1024 * 1024.0), 2));// 当前内存使用量,单位:"G" + sb.append(SEPARATOR); + sb.append(doubleFormat(memFree / (1024 * 1024 * 1024.0), 2));// 当前内存剩余量,单位:"G" + sb.append(SEPARATOR); + sb.append(doubleFormat(((memTotal - memFree) * 100.0) / memTotal, 1));// 内存使用率 + + StringBuffer sb2 = new StringBuffer(); +// sb2.append("内存总大小: " + doubleFormat(memTotal / (1024 * 1024 * 1024.0), 2) + "G, 现使用:" +// + doubleFormat(memUsed / (1024 * 1024 * 1024.0), 2) + "G, 剩余:" +// + doubleFormat(memFree / (1024 * 1024 * 1024.0), 2) + "G, 使用率:" +// + doubleFormat(((memTotal - memFree) * 100.0) / memTotal, 1) + "%"); + sb2.append("i18n_client.SystemInfo.memerySize_n81i: " + doubleFormat(memTotal / (1024 * 1024 * 1024.0), 2) + "G, i18n_client.SystemInfo.currentUsed_n81i:" + + doubleFormat(memUsed / (1024 * 1024 * 1024.0), 2) + "G, i18n_client.SystemInfo.spaceRemain_n81i:" + + doubleFormat(memFree / (1024 * 1024 * 1024.0), 2) + "G, i18n_client.SystemInfo.shiyonglv_n81i:" + + doubleFormat(((memTotal - memFree) * 100.0) / memTotal, 1) + "%"); + + detectInfo.getDetailDatas().add(sb.toString()); + detectInfo.setDescInfo(sb2.toString()); + + logger.debug("testPhysicalMemory--sb2=[ " + sb2.toString() + " ] -- tt=" + + doubleFormat(mem.getUsedPercent(), 1)); + } catch (SigarException e) + { + logger.error("Getting the exception of memory information", e); + return null; + } + + return detectInfo; + } + + // 资源信息(主要是硬盘已有的分区及其详细信息) + public DetectInfo testFileSystemInfo() + { + int num=0; + DetectInfo detectInfo = new DetectInfo(); + try + { + Sigar sigar = new Sigar(); + long allTotal = 0l; + long allUse = 0l; + // long allFree = 0l; + StringBuffer sb2 = new StringBuffer(); + String dirName = ""; + FileSystem fslist[] = sigar.getFileSystemList(); + for (int i = 0; i < fslist.length; i++) + { + FileSystem fs = fslist[i]; + try + { + FileSystemUsage usage = sigar.getFileSystemUsage(fs.getDirName()); + if (fs.getType() == 2) + {// 先取每个盘符的大小和剩余空间 + long total = usage.getTotal();// 文件系统总大小, 单位:"KB" + long free = usage.getFree();// 文件系统剩余大小, 单位:"KB" + String usePerc = doubleFormat(usage.getUsePercent() * 100, 1); // 文件系统资源的利用率 + + allTotal += total;// 文件系统总大小, 单位:"KB" + // allFree += free;// 文件系统剩余大小, 单位:"KB" + allUse += usage.getUsed();//文件系统使用大小, 单位:"KB" + + StringBuffer sb = new StringBuffer(); + sb.append(fs.getDirName()); + dirName +=fs.getDirName()+","; + sb.append(SEPARATOR); + sb.append(doubleFormat(total / (1024 * 1024.0), 2));// 文件系统总大小, + // 单位:"GB" + sb.append(SEPARATOR); + sb.append(doubleFormat(free / (1024 * 1024.0), 2));// 文件系统剩余大小, + // 单位:"GB" + sb.append(SEPARATOR); + sb.append(usePerc);// 文件系统资源的利用率 + sb.append(SEPARATOR); + if (checkFileSystemIsWrite(fs.getDirName())) + {// 文件系统是否可写 + sb.append("0");// 可写:0 + } else + { + sb.append("1");// 不可写:1 + num ++; + } + + detectInfo.getDetailDatas().add(sb.toString()); + +// sb2.append(Contants.DETEC_STATE_INFO_FORMATE_POINT+"【" + fs.getDirName() + "】大小 " +// + doubleFormat(total / (1024 * 1024.0), 2) + "G, 已使用 " +// + doubleFormat((total-free) / (1024 * 1024.0), 2) + "G, 剩余 " +// + doubleFormat(free / (1024 * 1024.0), 2) + "G, Usage 使用率 " +// + usePerc + "% ; "); + sb2.append(Contants.DETEC_STATE_INFO_FORMATE_POINT+"【" + fs.getDirName() + "】i18n_client.SystemInfo.size_n81i " + + doubleFormat(total / (1024 * 1024.0), 2) + "G, i18n_client.SystemInfo.used1_n81i " + + doubleFormat((total-free) / (1024 * 1024.0), 2) + "G, i18n_client.SystemInfo.spaceRemain_n81i " + + doubleFormat(free / (1024 * 1024.0), 2) + "G, i18n_client.SystemInfo.shiyonglv_n81i " + + usePerc + "% ; "); + } + } catch (SigarException e) + { + if (fs.getType() == 2) + throw e; + continue; + } + } + // 文件系统资源的总利用率 + // String allUsePerc = doubleFormat((allUse * 1.0 / allTotal) * 100, + // 1); + + if(num==detectInfo.getDetailDatas().size()){//所有硬盘不可写 主动告警 +// String msg = "磁盘"+dirName.substring(0,dirName.length()-1)+"只读"; + String msg = "i18n_client.SystemInfo.disk_n81i"+dirName.substring(0,dirName.length()-1)+"i18n_client.SystemInfo.readOnly_n81i"; + detectInfo.setDiskMsg(msg); + return detectInfo; + } + if(allUse==allTotal){//当磁盘满时候主动告警 +// String msg = "磁盘总大小"+doubleFormat(allTotal / (1024 * 1024.0), 2)+"G,总的使用率 100%,分区 "+dirName.substring(0,dirName.length()-1)+"剩余 0%"; + String msg = "i18n_client.SystemInfo.diskSize_n81i"+doubleFormat(allTotal / (1024 * 1024.0), 2)+"G,i18n_client.SystemInfo.zongShiYongLv_n81i,i18n_client.SystemInfo.zone_n81i "+dirName.substring(0,dirName.length()-1)+"i18n_client.SystemInfo.spaceRemain_n81i 0%"; + detectInfo.setDiskMsg(msg); + return detectInfo; + } + + DecimalFormat decimalFormat = new DecimalFormat("0.00"); +// sb2.insert(0, "磁盘总大小:" + doubleFormat(allTotal / (1024 * 1024.0), 2) + "G,已使用 "+decimalFormat.format(((double)allUse/(double)allTotal)*100)+"% ; "); + sb2.insert(0, "i18n_client.SystemInfo.diskSize_n81i:" + doubleFormat(allTotal / (1024 * 1024.0), 2) + "G,i18n_client.SystemInfo.used2_n81i "+decimalFormat.format(((double)allUse/(double)allTotal)*100)+"% ; "); + detectInfo.setDescInfo(sb2.toString()); + logger.debug("testFileSystemInfo--sb2=[ " + sb2.toString() + " ]"); + + } catch (SigarException e) + { + logger.error("Getting hard disk information abnormity", e); + return null; + } + + return detectInfo; + } + + // 获取网络流量等信息 + public DetectInfo testNetDataList() + { + DetectInfo detectInfo = new DetectInfo(); + try + { + Sigar sigar = new Sigar(); + String ifNames[] = sigar.getNetInterfaceList(); + if (ifNames.length > 0) + { + StringBuffer sb2 = new StringBuffer(); + int ethernetCnt = 0; + + // 2013-02-26 设备名的处理并去重,这个是针对一块网卡有多个逻辑配置 如 eth0和eth0:1,只取eth0即可 + List nameList = new LinkedList(); + for (int i = 0; i < ifNames.length; i++) + { + String name = ifNames[i]; + + if (name.indexOf(":") != -1) + { + name = name.substring(0, name.indexOf(":")); + } + + if (!nameList.contains(name)) + { + nameList.add(name); + } + } + + for (int i = 0; i < nameList.size(); i++) + { + String name = nameList.get(i); + + NetInterfaceConfig ifconfig = sigar.getNetInterfaceConfig(name); + logger.debug("testNetDataList----type= " + ifconfig.getType()); + + // *** 网卡类型:ethernet, Local Loopback(本地环回网卡) + // *** 这里只取 ethernet 网卡类型 + if ((ifconfig.getFlags() & NetFlags.IFF_LOOPBACK) > 0) + { + continue; + } + /* + * if ((ifconfig.getFlags() & NetFlags.IFF_POINTOPOINT) > 0) { + * continue; } + */ + // 2013-4-22 针对LInux,按名称过滤掉sit0,实际命令查看类型为:IPv6-in-IPv4 + if (name.equals("sit0")) + { + continue; + } + // 2013-5-23 针对Win7取到的网卡数量太多问题 + if ((ifconfig.getFlags() & NetFlags.IFF_BROADCAST) <= 0) + {// broadcast地址无效 + continue; + } + if ((ifconfig.getFlags() & NetFlags.IFF_MULTICAST) <= 0) + {// 不支持multicast + continue; + } + ethernetCnt++; + + if ((ifconfig.getFlags() & NetFlags.IFF_UP) <= 0) + { + // print("!IFF_UP...skipping getNetInterfaceStat"); +// sb2.append(Contants.DETEC_STATE_INFO_FORMATE_POINT+name + " 不可用; "); + sb2.append(Contants.DETEC_STATE_INFO_FORMATE_POINT+name + " i18n_client.SystemInfo.disable_n81i; "); + continue; + } + + NetInterfaceStat ifstat; + try + { + ifstat = sigar.getNetInterfaceStat(name); + } catch (SigarException e) + { + continue; + } + Long rxPackets1 = ifstat.getRxPackets();// 接收的总包裹数 + Long txPackets1 = ifstat.getTxPackets();// 发送的总包裹数 + Long rxBytes1 = ifstat.getRxBytes();// 接收到的总字节数 + Long txBytes1 = ifstat.getTxBytes();// 发送的总字节数 + Long rxErrors1 = ifstat.getRxErrors();// 接收到的错误包数 + Long txErrors1 = ifstat.getTxErrors();// 发送数据包时的错误数 + Long rxDropped1 = ifstat.getRxDropped();// 接收时丢弃的包数 + Long txDropped1 = ifstat.getTxDropped();// 发送时丢弃的包数 + + int seconds = 5; + try + { + Thread.sleep(seconds * 1000);// 等待5秒 + } catch (InterruptedException e) + { + e.printStackTrace(); + } + + ifstat = sigar.getNetInterfaceStat(name); + Long rxPackets2 = ifstat.getRxPackets();// 接收的总包裹数 + Long txPackets2 = ifstat.getTxPackets();// 发送的总包裹数 + Long rxBytes2 = ifstat.getRxBytes();// 接收到的总字节数 + Long txBytes2 = ifstat.getTxBytes();// 发送的总字节数 + Long rxErrors2 = ifstat.getRxErrors();// 接收到的错误包数 + Long txErrors2 = ifstat.getTxErrors();// 发送数据包时的错误数 + Long rxDropped2 = ifstat.getRxDropped();// 接收时丢弃的包数 + Long txDropped2 = ifstat.getTxDropped();// 发送时丢弃的包数 + + + // 添加监测日志,用于检查网络流量出现负值的原因 + logger.debug(" bps 输入: rxBytes1:" + rxBytes1 + ", rxBytes2:" + rxBytes2); + logger.debug(" bps 输出: txBytes1:" + txBytes1 + ", txBytes2:" + txBytes2); + logger.debug(" pps 输入: rxPackets1:" + rxPackets1 + ", rxPackets2:" + rxPackets2); + logger.debug(" pps 输出: txPackets1:" + txPackets1 + ", txPackets2:" + txPackets2); + + Long speed = ifstat.getSpeed() / (1000 * 1000);// 带宽:Mbps + // bps 输入:((第二次接收的总字节数-第一次)*8)/(时间秒*1000*1000)Mbps + // String rx_bps = doubleFormat(((rxBytes2 - rxBytes1) * 8) + // / (seconds * 1000 * 1000), 2); + // bps 输入:((第二次接收的总字节数-第一次)*8)/(时间秒)bps + String rx_bps = doubleFormat(((rxBytes2 - rxBytes1) * 8) / (seconds), 2); + // bps 输出:((第二次发送的总字节数-第一次)*8)/(时间秒)bps + String tx_bps = doubleFormat(((txBytes2 - txBytes1) * 8) / (seconds), 2); + // pps 输入:(第二次接收的总包裹数-第一次)/时间秒 + Long rx_pps = (rxPackets2 - rxPackets1) / seconds; + // pps 输出:(第二次发送的总包裹数-第一次)/时间秒 + Long tx_pps = (txPackets2 - txPackets1) / seconds; + Long rx_errorPerc = 0l;// 接收错包率 + Long tx_errorPerc = 0l;// 发送错包率 + Long rx_droppedPerc = 0l;// 接收丢包率 + Long tx_droppedPerc = 0l;// 发送丢包率 + if (rxPackets2 - rxPackets1 > 0) + { + rx_errorPerc = (rxErrors2 - rxErrors1) / (rxPackets2 - rxPackets1) * 100;// 接收错包率 + rx_droppedPerc = (rxDropped2 - rxDropped1) / (rxPackets2 - rxPackets1) + * 100;// 接收丢包率 + } + if (txPackets2 - txPackets1 > 0) + { + tx_errorPerc = (txErrors2 - txErrors1) / (txPackets2 - txPackets1) * 100;// 发送错包率 + tx_droppedPerc = (txDropped2 - txDropped1) / (txPackets2 - txPackets1) + * 100;// 发送丢包率 + } + + StringBuffer sb = new StringBuffer(); + sb.append(name);// 网卡名称 + sb.append(SEPARATOR); + sb.append(rxPackets2);// 接收的总包裹数 + sb.append(SEPARATOR); + sb.append(txPackets2);// 发送的总包裹数 + sb.append(SEPARATOR); + sb.append(rxBytes2);// 接收到的总字节数 + sb.append(SEPARATOR); + sb.append(txBytes2);// 发送到的总字节数 + sb.append(SEPARATOR); + sb.append(rxErrors2);// 接收到的错误包数 + sb.append(SEPARATOR); + sb.append(txErrors2);// 发送到的错误包数 + sb.append(SEPARATOR); + sb.append(rxDropped2);// 接收时丢弃的包数 + sb.append(SEPARATOR); + sb.append(txDropped2);// 发送时丢弃的包数 + sb.append(SEPARATOR); + sb.append(speed);// 带宽:Mbps + sb.append(SEPARATOR); + sb.append(rx_bps);// bps 输入:Mbps + sb.append(SEPARATOR); + sb.append(tx_bps);// bps 输出:Mbps + sb.append(SEPARATOR); + sb.append(rx_pps);// pps 输入:每秒接收包数 + sb.append(SEPARATOR); + sb.append(tx_pps);// pps 输出:每秒发送包数 + sb.append(SEPARATOR); + sb.append(rx_errorPerc);// 接收错包率 + sb.append(SEPARATOR); + sb.append(tx_errorPerc);// 发送错包率 + sb.append(SEPARATOR); + sb.append(rx_droppedPerc);// 接收丢包率 + sb.append(SEPARATOR); + sb.append(tx_droppedPerc);// 发送丢包率 + detectInfo.getDetailDatas().add(sb.toString()); + +// sb2.append(Contants.DETEC_STATE_INFO_FORMATE_POINT+name + " 带宽" + speed + "Mbps, 输入" + rx_bps + "bps、" + rx_pps +// + "pps, 输出" + tx_bps + "bps、" + tx_pps + "pps; "); + sb2.append(Contants.DETEC_STATE_INFO_FORMATE_POINT+name + " i18n_client.SystemInfo.netSpeed_n81i" + speed + "Mbps, i18n_client.SystemInfo.input_n81i" + rx_bps + "bps、" + rx_pps + + "pps, Output" + tx_bps + "bps、" + tx_pps + "pps; "); + } +// sb2.insert(0, ethernetCnt + "个逻辑网卡: "); + sb2.insert(0, ethernetCnt + "i18n_client.SystemInfo.insert_n81i: "); + detectInfo.setDescInfo(sb2.toString()); + logger.debug("testNetDataList----" + sb2); + } + + } catch (SigarException e) + { + logger.error("Obtaining network information abnormity", e); + return null; + } + return detectInfo; + } + + public DetectInfo testSystemDate() + { + DetectInfo detectInfo = new DetectInfo(); + try + { + String sysDateStr = getServerSystemDate(); + if (sysDateStr != null) + { + long sysDate = Long.parseLong(sysDateStr);// 服务器系统时间 + long localDate = System.currentTimeMillis();// 客户机系统时间 + long timeDelay = Math.abs(DateUtil.getMinutesFromBeginToEnd(sysDate, localDate)); + + detectInfo.getDetailDatas().add(sysDate + SEPARATOR + localDate + SEPARATOR + + timeDelay); + detectInfo.setDescInfo("server:" + + DateUtil.getStingDate(DateUtil.YYYY_MM_DD_HH24_MM_SS, new Date(sysDate)) + + " agent:" + + DateUtil + .getStingDate(DateUtil.YYYY_MM_DD_HH24_MM_SS, new Date(localDate))); + } else + { +// detectInfo.setDescInfo("获取DataController系统时间失败"); + detectInfo.setDescInfo("i18n_client.SystemInfo.getSysTimeErr_n81i"); + } + + } catch (Exception e) + { + logger.error("Getting the time anomaly of the system", e); + return null; + } + return detectInfo; + } + + /* + * 获取服务端系统时间 + */ + private static String getServerSystemDate() + { + String date = null; + try + { + Future future = Common.service.submit(new SSLClient( + Thread.currentThread().getName(), CommonSocket.REQ_SERVER_SYSTEMDATE, null)); + String msg = (String) future.get(); + if (Contants.isSucessByResult(msg)) + { + date = Contants.getDescByResult(msg); + } + } catch (Exception e) + { + logger.error("Getting the time exception of the server system:" + Utils.printExceptionStack(e)); + date = null; + } + + return date; + } + + public DetectInfo testProcessInfo(String pidFile, final String procPath, String procSearchKey, + boolean isStart) + { + DetectInfo detectInfo = new DetectInfo(); + try + { + Object[] objArr = ProcessUtil.checkPidAndGetPid(pidFile, procSearchKey); + int isExistFlag = Integer.parseInt(objArr[0].toString()); + String pidInfo = objArr[1].toString(); + + if (isStart && isExistFlag == 0) + {// Agent启动且进程不存在,启动 + logger.info("进程“" + procPath + "”不存在,正在启动……"); + // -------------------启动进程开始 + final String threadName = Thread.currentThread().getName(); + Future future = Common.service.submit(new Runnable() + { + + @Override + public void run() + { + thread = Thread.currentThread(); + Thread.currentThread().setName(threadName); + try + { + ProcessUtil.runExec(procPath, null, null, null); + } catch (IOException e) + { + logger.error(e); + } + } + + }); + // ----获取最大等待时间(单位秒) + long delay = 3 * 60;// 3分钟 + // ----超过一定时间,终止执行线程,返回结果超时 + try + { + future.get(delay, TimeUnit.SECONDS); + } catch (TimeoutException e) + { + if (thread != null && thread.isAlive()) + { + thread.stop(); + logger.debug(procPath + "---testProcessInfo Timeout stop thread--" + + thread.isAlive()); + } + future.cancel(true); + logger.info("执行“" + procPath + "”, 超时"); + } + // -------------------启动进程结束 + // -------------------检查PID + objArr = ProcessUtil.checkPidAndGetPid(pidFile, procSearchKey); + isExistFlag = Integer.parseInt(objArr[0].toString()); + pidInfo = objArr[1].toString(); + if (isExistFlag != 0) + { + logger.info("进程“" + procPath + "”启动成功"); + } else + { + logger.info("进程“" + procPath + "”启动失败"); + } + } + logger.debug("testProcessInfo pidInfo --> " + pidInfo); + if(isExistFlag == 0){ + StringBuffer sb = new StringBuffer(); + //sb.append(CpuPerc.format(procCpu.getTotal() * 1.0 / cpuTotal));// 进程的CPU使用率 + sb.append(SEPARATOR); + //sb.append(doubleFormat((memUse * 1.0 / sigar.getMem().getTotal()) * 100, 1) + "%");// 进程的内存使用率 + sb.append(SEPARATOR); + //sb.append(procCpu.getStartTime());// 进程的启动时间 + sb.append(SEPARATOR); + sb.append("NO");// 进程状态 + sb.append(SEPARATOR); + //sb.append(state.getPriority());// 进程优先级 + + int index = 0; + String[] tmp = sb.toString().split(SEPARATOR); + + detectInfo.getDetailDatas().add(sb.toString().replace("%", "")); + detectInfo.setDescInfo(pidInfo); + return detectInfo; + } + if (isExistFlag != 1) + {// 进程不存在或找到多个进程 + detectInfo.setDescInfo(pidInfo); + return detectInfo; + } else + { + long pid = Long.parseLong(pidInfo); + + Sigar sigar = new Sigar(); + // 获取进程的CPU信息 + ProcCpu procCpu = sigar.getProcCpu(pid); + long cpuTotal = 0; + Cpu[] cpuArr = sigar.getCpuList(); + for (Cpu cpu2: cpuArr) + { + cpuTotal += cpu2.getTotal(); + } + logger.debug("testProcessInfo---->cpuTotal=" + cpuTotal); + logger.debug("testProcessInfo---->cpuUse=" + procCpu.getTotal()); + + ProcState state = sigar.getProcState(pid); + + Ps ps = new Ps(); + List list = ps.getInfo(sigar, pid); + String memUseStr = ""; + for (int i = 0; i < list.size(); i++) + { + switch (i) + { + // case 0 : System.out.print("--Pid=" + list.get(0)); + // break; + // case 1 : System.out.print("\tUser=" + list.get(1)); + // break; + // case 2 : System.out.print("\tStartTimes=" + + // list.get(2)); break; + // case 3 : memSizeStr= list.get(3); break; + case 4: + memUseStr = list.get(4); + break; + // case 5 : logger.debug("testProcessInfo---->MemHare=" + // + list.get(5)); break; + // case 6 : System.out.print("\tState=" + list.get(6)); + // break; + // case 7 : System.out.print("\tCpuTime=" + + // list.get(7)); break; + // case 8 : System.out.println("\tName=" + list.get(8)); + // break; + default: + break; + } + } + double memUse = Double.parseDouble(memUseStr.substring(0, memUseStr.length() - 1)); + char useUnit = memUseStr.toUpperCase().charAt(memUseStr.length() - 1); + switch (useUnit) + { + case 'K': + memUse = memUse * 1024; + break; + case 'M': + memUse = memUse * 1024 * 1024; + break; + case 'G': + memUse = memUse * 1024 * 1024 * 1024; + break; + case 'T': + memUse = memUse * 1024 * 1024 * 1024 * 1024; + break; + case 'P': + memUse = memUse * 1024 * 1024 * 1024 * 1024 * 1024; + break; + default: + break; + } + + logger.debug("testProcessInfo---->memTotal=" + sigar.getMem().getTotal() / 1024 + + "KB"); + logger.debug("testProcessInfo---->memUseStr=" + memUseStr); + logger.debug("testProcessInfo---->memUse=" + memUse); + + StringBuffer sb = new StringBuffer(); + sb.append(CpuPerc.format(procCpu.getTotal() * 1.0 / cpuTotal));// 进程的CPU使用率 + sb.append(SEPARATOR); + sb.append(doubleFormat((memUse * 1.0 / sigar.getMem().getTotal()) * 100, 1) + "%");// 进程的内存使用率 + sb.append(SEPARATOR); + sb.append(procCpu.getStartTime());// 进程的启动时间 + sb.append(SEPARATOR); + sb.append(state.getState());// 进程状态 + sb.append(SEPARATOR); + sb.append(state.getPriority());// 进程优先级 + + int index = 0; + String[] tmp = sb.toString().split(SEPARATOR); + StringBuffer sb2 = new StringBuffer(); + sb2.append("cpuUsage:" + tmp[index++]); + sb2.append(" memUsage:" + tmp[index++]); + sb2.append(" startTime:" + + DateUtil.getStingDate(DateUtil.YYYY_MM_DD_HH24_MM_SS, new Date(Long + .parseLong(tmp[index++])))); + sb2.append(" state:" + tmp[index++]); + sb2.append(" priority:" + tmp[index++]); + + detectInfo.getDetailDatas().add(sb.toString().replace("%", "")); + detectInfo.setDescInfo(sb2.toString()); + + logger.debug("testProcessInfo---->" + sb2.toString()); + + } + } catch (Exception e) + { + logger.error("Getting process information abnormity", e); + return null; + } + + return detectInfo; + } + + public DetectInfo testSystemInfo() + { + DetectInfo detectInfo = new DetectInfo(); + try + { + Sigar sigar = new Sigar(); + + StringBuffer sb = new StringBuffer(); + sb.append(sigar.getNetInfo().getHostName());// 主机名称 + sb.append(SEPARATOR); + // 操作系统和发行版本 (os.getVendorName() + " " + os.getVersion()) + // Linux: uname -r;uname -i;lsb_release -d| cut -d: -f2| cut -f2 + // Windows: ver + String operateSystem = Utils.getOperateSystem(); + sb.append(operateSystem);// 操作系统和发行版本 + sb.append(SEPARATOR); + sb.append(sigar.getCpuInfoList().length);// CPU核数 + sb.append(SEPARATOR); + sb.append(sigar.getCpuInfoList()[0].getMhz());// CPU主频 + sb.append(SEPARATOR); + String totalMem = doubleFormat(sigar.getMem().getTotal() / (1024 * 1024 * 1024.0), 2); + sb.append(totalMem);// 内存大小,单位:G + sb.append(SEPARATOR); + sb.append(doubleFormat(sigar.getSwap().getTotal() / (1024 * 1024 * 1024.0), 2));// SWAP大小,单位:G + sb.append(SEPARATOR); + + long allTotal = 0; + // **************** 以下是各分区大小 ******************* // + List diskDatas = new ArrayList(); + FileSystem fslist[] = sigar.getFileSystemList(); + for (int i = 0; i < fslist.length; i++) + { + FileSystem fs = fslist[i]; + try + { + FileSystemUsage usage = sigar.getFileSystemUsage(fs.getDirName()); + if (fs.getType() == 2) + {// 先取每个盘符的大小和剩余空间 + long total = usage.getTotal();// 文件系统大小, 单位:"KB" + allTotal += total;// 文件系统总大小, 单位:"KB" + // 各分区名称和大小(单位G) + diskDatas.add(new String[] { fs.getDirName(), + doubleFormat(total / (1024 * 1024.0), 2) }); + } + } catch (SigarException e) + { + if (fs.getType() == 2) + throw e; + continue; + } + } + // ---------------- 以上是各分区大小 ------------------- // + sb.append(doubleFormat(allTotal / (1024 * 1024.0), 2));// 硬盘总大小,单位:G + sb.append(SEPARATOR); + + int ethernetCnt = 0; + // **************** 以下是各网卡状态 ******************* // + List netDatas = new ArrayList(); + String ifNames[] = sigar.getNetInterfaceList(); + if (ifNames.length > 0) + { + String defaultGateWay = sigar.getNetInfo().getDefaultGateway(); + for (int i = 0; i < ifNames.length; i++) + { + String name = ifNames[i]; + + NetInterfaceConfig ifconfig = sigar.getNetInterfaceConfig(name); + + // *** 网卡类型:ethernet, Local Loopback(本地环回网卡) + // *** 这里只取 ethernet 网卡类型 + if ((ifconfig.getFlags() & NetFlags.IFF_LOOPBACK) > 0) + { + continue; + } + /* + * if ((ifconfig.getFlags() & NetFlags.IFF_POINTOPOINT) > 0) { + * continue; } + */ + // 2013-4-22 针对LInux,按名称过滤掉sit0,实际命令查看类型为:IPv6-in-IPv4 + if (name.equals("sit0")) + { + continue; + } + // 2013-5-23 针对Win7取到的网卡数量太多问题 + if ((ifconfig.getFlags() & NetFlags.IFF_BROADCAST) <= 0) + {// broadcast地址无效 + continue; + } + if ((ifconfig.getFlags() & NetFlags.IFF_MULTICAST) <= 0) + {// 不支持multicast + continue; + } + ethernetCnt++; + +// String state = "可用"; + String state = "Available"; + if ((ifconfig.getFlags() & NetFlags.IFF_UP) <= 0) + {// 网卡状态: 2050 网络电缆被拔出 2115 已连接上 +// state = "不可用"; + state = "Unavailable"; + } + String speed = null; + try + { + NetInterfaceStat ifstat = sigar.getNetInterfaceStat(name); + speed = ifstat.getSpeed() / (1000 * 1000) + "";// 带宽:Mbps + } catch (SigarException e) + { + speed = ""; + } + + netDatas.add(new String[] { name, // 网卡名称 + state, // 网卡状态 + speed, // 带宽 + ifconfig.getAddress(), // IP + ifconfig.getNetmask(), // 子网掩码 + defaultGateWay, // 网关 + ifconfig.getHwaddr() // Mac地址 + }); + } + } + // System.out.println(sigar.getNetInfo().getDefaultGateway()); + // ---------------- 以上是各网卡状态 ------------------- // + sb.append(ethernetCnt);// 网卡数量 + + detectInfo.getDetailDatas().add(sb.toString()); + + StringBuffer sb2 = new StringBuffer(); +// sb2.append(sigar.getNetInfo().getHostName() + ":" + operateSystem + ", " +// + sigar.getCpuInfoList().length + "核CPU, " + sigar.getCpuInfoList()[0].getMhz() +// + "MHz, " + totalMem + "GB的内存, " + doubleFormat(allTotal / (1024 * 1024.0), 2) +// + "GB的硬盘, " + ethernetCnt + "个逻辑网卡"); + sb2.append(sigar.getNetInfo().getHostName() + ":" + operateSystem + ", " + + sigar.getCpuInfoList().length + "i18n_client.SystemInfo.message.core_n81i CPU, " + sigar.getCpuInfoList()[0].getMhz() + + "MHz, " + totalMem + "i18n_client.SystemInfo.message.memery_n81i, " + doubleFormat(allTotal / (1024 * 1024.0), 2) + + "i18n_client.SystemInfo.message.disk_n81i, " + ethernetCnt + "i18n_client.SystemInfo.message.netcard_n81i"); + detectInfo.setDescInfo(sb2.toString()); + logger.debug("testSystemInfo--sb2--" + sb2.toString()); + + Map> relatedDataMap = new HashMap>(); + relatedDataMap.put("disk", diskDatas); + relatedDataMap.put("net", netDatas); + detectInfo.setRelatedDatas(relatedDataMap); + + } catch (Exception e) + { + logger.error("Getting the information anomaly of the system", e); + return null; + } + + return detectInfo; + } + + public static String getStartComputerTime() + { + String value = ""; + Sigar sigar = new Sigar(); + try + { + Uptime uptime = sigar.getUptime(); + Double d = new Double(uptime.getUptime()); + Calendar cal = Calendar.getInstance(); + cal.add(Calendar.SECOND, -d.intValue()); + + value = cal.getTimeInMillis() + ""; + } catch (SigarException e) + { + logger.error("Getting the boot time anomaly", e); + return value; + } + + return value; + } + + private String doubleFormat(double val, int xsws) + { +// String pattern = "#."; + String pattern = "0."; + if (xsws < 1) + { + xsws = 1; + } + for (int i = 1; i <= xsws; i++) + { + pattern += "0"; + } + + String temp = new DecimalFormat(pattern).format(val); +// if (val < 1) +// { +// return "0" + temp; +// } else +// { +// return temp; +// } + return temp; + } + + /** + * 检查硬盘是否可写:在指定盘符目录下写指定字节大小的文件,写异常-不可写,正常-可写 + * + * @param fsDirName + * 盘符 + * @return + */ + private boolean checkFileSystemIsWrite(String fsDirName) + { + boolean isWrite = true; + OutputStreamWriter fos = null; + File file = new File(fsDirName + File.separator + "writetest.temp"); + logger.debug("checkFileSystemIsWrite---file path = " + file.getAbsolutePath()); + try + { + fos = new OutputStreamWriter(new FileOutputStream(file), "utf-8"); +// fos.write("测试硬盘是否可写,现在开始写入文件\n"); + fos.write("i18n_client.SystemInfo.outputTest_n81i"); + fos.flush(); + } catch (IOException e) + { + logger.error("Test whether the hard disk can be written:" + e.getMessage()); + isWrite = false; + } finally + { + if (fos != null) + { + try + { + fos.close(); + } catch (IOException e) + { + } + } + } + if (file.exists()) + {// 不管是否写异常都将删除文件 + file.delete(); + logger.debug("checkFileSystemIsWrite---delete file = " + file.getAbsolutePath()); + } + return isWrite; + } + + public SystemInfo() + { + } + +} diff --git a/src/com/nis/systeminfo/thread/GetInfoRun.java b/src/com/nis/systeminfo/thread/GetInfoRun.java new file mode 100644 index 0000000..17cf8a2 --- /dev/null +++ b/src/com/nis/systeminfo/thread/GetInfoRun.java @@ -0,0 +1,592 @@ +package com.nis.systeminfo.thread; + +import java.io.File; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + +import com.nis.nmsclient.common.Contants; +import com.nis.nmsclient.common.SysConfig; +import com.nis.nmsclient.config.DetecConfOper; +import com.nis.nmsclient.model.AlarmInfo; +import com.nis.nmsclient.model.SetInfo; +import com.nis.nmsclient.thread.alarm.AlarmUtil; +import com.nis.nmsclient.util.DateUtil; +import com.nis.nmsclient.util.FileWrUtil; +import com.nis.nmsclient.util.Utils; +import com.nis.systeminfo.model.DetectInfo; +import com.nis.systeminfo.model.SystemInfo; + +/** + * 客户端读取本机信息,并写入到.csv文件的具体实现体 + * + */ +public class GetInfoRun implements Runnable{ + Logger logger = Logger.getLogger(GetInfoRun.class); + private String name; + private SetInfo setInfo; // 当前线程读取的信息要存入的表,如CPU信息表、内存信息表等 + private Date startTime;// 服务启动时间 + private List alarmInfos; + + private int diskUsageTime=0; + private int cpuUsageTime=0; + private String cpuUsageName=""; + private String diskUsageName=""; + + private List detailDatas ; + + //暂存各告警字段连续超过告警值的次数 + //public static Map alarmTimes = new HashMap(); + + //暂存各告警信息告警状态 + //public static Map alarmStates = new HashMap(); + + private int alarmTimes = 0; + private boolean alarmState = false; + + private String firstPerformData=""; + + public GetInfoRun(String name, SetInfo setInfo, Date startTime, List alarmInfos) { + super(); + this.name = name; + this.setInfo = setInfo; + this.startTime = startTime; + this.alarmInfos = alarmInfos; + //如果设置是process类型,且设置名称是nmsclient,即是自身则设置进程PID文件 + if (Contants.SYS_CHECK_TYPE_PROCESS.equalsIgnoreCase(setInfo.getCheckTypeName()) + && Contants.SYS_CHECK_TYPE_PROCESS_NMSAGENT + .equalsIgnoreCase(setInfo.getProcessIden())) { + setInfo.setProcessFile(Contants.localAgentPidFile); + } + } + + public void run() { + Thread.currentThread().setName(name); + + Date writeDate = new Date(); + int checkTimes = 0;//尝试次数 + //初始化值 + String filePath = Contants.localDataFilePath + + File.separator + + DetecConfOper.getFileName(setInfo.getCheckTypeName(), setInfo + .getProcessIden(), null) + File.separator; + String fileName = DateUtil.getStingDate(DateUtil.YYYYMMDDHH24MMSS, writeDate) + ".csv"; + // 针对进程,是NC启动还是手动启动 + boolean isAgentStart = ("0".equals(setInfo.getIsControlStart()) ? false : true); + + do { + checkTimes++; + try { + /* + * 2013-4-11 数据顺序调整如下: + * 总数据:本机IP,监测设置ID,监测类别,进程名称(监测类别设置名称),监测服务启动时间,检测时延(秒),本次检测时间,尝试次数,下次计划监测时间, + * 执行状态是否成功是否正常(用于报警:-1执行失败,0不正常,1正常),状态信息(描述信息),性能数据 + * 详细信息:details,详细信息条数(要入到对应的监测类别信息表的数据条数) + * 告警列序号,告警级别,告警值,监测具体数据信息(多列),,,, + */ + + // detailDatas存放监测具体数据信息(可能多条,如多个网卡),descInfo存放状态信息 + DetectInfo detectInfo = new SystemInfo().getDetectInfo(setInfo + .getCheckTypeName(), setInfo.getProcessFile(), setInfo + .getProcessPath(), setInfo.getProcessSearchKeyCode(), isAgentStart); + + String checkDelayTime = getCheckDelayTime(writeDate);// 检测时延 + + // ------- 数据状态(告警)和详细监测数据组织 + int totalStatus = Contants.DETECTION_STATUS_NORMAL; + int totalAlarmLevel = 99; + String totalShowNum ="";//告警序列号,取告警级别高的showNum add by jinsj for 紧急告警 + StringBuffer functionSb = new StringBuffer(); + List detailDataList = new LinkedList(); + if (detectInfo == null || detectInfo.getDetailDatas() == null || detectInfo.getDetailDatas().size() == 0) {// 执行失败 + totalStatus = Contants.DETECTION_STATUS_FAILURE; + // detectInfo不为空,即无具体的详细数据,有描述信息(目前是针对进程与系统时间) + if (detectInfo != null){ + // 如果是进程监测, 找不到进程或找到多个进程时,告警;如果时间差监测,获取DC系统时间失败,告警 + String alarmMsg = detectInfo.getDescInfo(); + AlarmUtil.sendAlarmMsg(setInfo.getId(), setInfo.getCheckTypeName(), setInfo.getProcessIden(), + new Date(), new Date(), 1, Contants.DETECTION_STATUS_FAILURE, alarmMsg); + } + logger.info("预设监测 setId: " + this.setInfo.getId() + " > " + + this.setInfo.getCheckTypeName() + "_" + setInfo.getProcessIden() + ",获取数据失败"); + }else if(!StringUtils.isBlank(detectInfo.getDiskMsg())){ + //出现硬盘不可写或磁盘满 + AlarmUtil.sendAlarmMsg(setInfo.getId(), setInfo.getCheckTypeName(), setInfo.getProcessIden(), + new Date(), new Date(), 0, Contants.DETECTION_STATUS_ABNORMAL, detectInfo.getDiskMsg()); + return ; + }else {// 即正常生成详细监测数据 + detailDatas = detectInfo.getDetailDatas(); + for(int i=0; i Integer.parseInt(alarmArr[4])){// 将更高的告警级别赋给总告警级别 + totalAlarmLevel = Integer.parseInt(alarmArr[4]); + totalShowNum = alarmArr[5]; + } + } + if(detailDatas.size()>1 && alarmArr[3].length()>0){ + functionSb.append("【" + detailData[0] + "】 " + alarmArr[3] + "
");// 组织性能数据 + }else{ + functionSb.append(alarmArr[3]);// 组织性能数据 + } + for (int j = 0; j < detailData.length; j++) {// 监测具体数据信息 + dataArr[index + j] = detailData[j]; + } + + detailDataList.add(dataArr); + } + } + if(StringUtils.isNotBlank(firstPerformData)){ + functionSb.insert(0,firstPerformData+"
"); + } + // ------- 主动告警 + String totalAlarmInfo = null; + if(totalStatus == Contants.DETECTION_STATUS_NORMAL){ + // 本次数据正常,看原本的状态:若是告警状态,则发送恢复通知;若是正常状态,则不变 + if(alarmState){ + totalAlarmInfo = "【i18n_client.GetInfoRun.totalAlarmInfo1_n81i】
" + functionSb.toString(); + } + alarmState = false; + alarmTimes = 0; + }else if(totalStatus == Contants.DETECTION_STATUS_ABNORMAL){//状态异常 + alarmTimes ++; + if(!alarmState){// 本次数据不正常,看原本的状态:若是正常状态,则发送告警,此主动告警也只有一次,除非监测恢复正常,之后又异常 + if(setInfo!=null && "process".equalsIgnoreCase(setInfo.getCheckTypeName())) {//如果是进程监测 + totalAlarmInfo = functionSb.toString(); + }else { + totalAlarmInfo = "【i18n_client.GetInfoRun.totalAlarmInfo2_n81i】
" + functionSb.toString(); + } + }else if(alarmTimes == Contants.overAlarmValTimes && alarmState){//若原本的状态是告警状态,则判断是否连续几次达到告警值,次数会一直累积,知道监测恢复正常,所以如果一直异常,则也只告警一次连续4次异常 + totalAlarmInfo = "【i18n_client.GetInfoRun.totalAlarmInfo3_n81i】
" + functionSb.toString(); + } + alarmState = true; + } + if(totalAlarmInfo!=null){ + //2014-5-12 add:根据配置的参数,决定是否启用监测数据超过设定值时的主动告警 + Boolean activeAlarmStart = Contants.ACTIIVE_ALARM_START; + if(totalStatus == Contants.DETECTION_STATUS_NORMAL ||//数据恢复主动告警 + (activeAlarmStart && totalStatus == Contants.DETECTION_STATUS_ABNORMAL)) {//数据异常主动告警 + AlarmUtil.sendAlarmMsg(setInfo.getId(), setInfo.getCheckTypeName(), setInfo.getProcessIden(), + new Date(), new Date(), totalAlarmLevel, totalStatus, totalAlarmInfo,totalShowNum); + } + } + // ------- 总监测数据组织 + int index = 0; + String[] totalData = new String[12]; + totalData[index++] = getUUID();// UUID + totalData[index++] = setInfo.getId() + "";// 监测设置ID + totalData[index++] = setInfo.getCheckTypeName();// 监测类别 + totalData[index++] = setInfo.getProcessIden();// 进程名称 + totalData[index++] = getStartClientTime();// 监测服务启动时间 + totalData[index++] = checkDelayTime;// 检测时延(秒) + totalData[index++] = writeDate.getTime() + "";// 本次检测时间 + totalData[index++] = checkTimes + "";// 尝试次数 + totalData[index++] = getNextCheckTime(writeDate);// 下次计划监测时间 + totalData[index++] = totalStatus + "";// 执行状态是否成功是否正常 + totalData[index++] = (detectInfo == null ? "" : detectInfo.getDescInfo());// 状态信息(描述信息) + totalData[index++] = StringUtils.isBlank(functionSb.toString())?detectInfo.getDescInfo():functionSb.toString();// 性能数据 + + List dataList = new LinkedList(); + // 总数据 + dataList.add(totalData); + // 详细信息 + dataList.add(new String[]{"details", detailDataList.size() + ""});// details(解析标识),详细信息条数 + dataList.addAll(detailDataList);// 具体的详细数据 + // 特殊数据定制(目前是针对系统信息监测systeminfo) + if (detectInfo!=null && detectInfo.getRelatedDatas() != null) { + Set>> set = detectInfo.getRelatedDatas().entrySet(); + for(Map.Entry> entry : set){ + dataList.add(new String[]{entry.getKey(), entry.getValue().size() + ""});// 解析标识, 行数(当前解析标识指定的类型有多少条数据) + dataList.addAll(entry.getValue());// 多条数据 + } + } + + for(String[] val : dataList){ +// logger.debug(Arrays.toString(val));//i18nlog + } + + File file = new File(filePath); + if (!file.exists()) { + file.mkdirs(); + } + file = new File(filePath + fileName + ".tp"); + FileWrUtil.csvFilePrinter(file, Contants.charset, dataList); + + File file2 = new File(filePath + fileName); + file.renameTo(file2); + break; + } catch (Exception e) { + logger.error("Client write file" + fileName + "error: " + Utils.printExceptionStack(e)); + continue; + }finally{ + diskUsageTime=0; + cpuUsageTime=0; + cpuUsageName=""; + diskUsageName=""; + } + } while (checkTimes < setInfo.getCheckMaxTimes()); + + } + + /** + * 获得当前的报警设置信息,与相应字段值比较 + * 2014-5-15 update: 标识字段,标识 + */ + private String[] getAlarmState(String[] sysData){ + // strs数组数据依次为:告警序列号、告警级别、告警值、性能数据、本次最高告警级别 + String[] strs = new String[]{"", "", "", "", "",""}; + if(alarmInfos==null){ + return strs; + } + int maxAlarmLevel = 99; + String maxShowNum = "" ; + for (AlarmInfo alarm : alarmInfos) { +// logger.info("*****marker:"+alarm.getMarker()); + if (sysData.length < alarm.getShowNum()) {// 得到的数据个数和告警列数比较 + continue; + } + String data = sysData[alarm.getShowNum() - 1]; + boolean alarmFlag = false; + + /** + * 2014-5-15 add: + * 1.指定了特定的标识: + * (1).当前标识非空:不在指定标识内,则不做告警判断;在,则做告警判断 + * (2).当前标识为空:空不在指定标识内,不做告警判断 + * 2.未指定特定的标识:所有标识都进行告警判断 + */ + String marker = alarm.getMarker(); +// Integer markerShowNum = 1;//先默认取第一个 + Integer markerShowNum = alarm.getMarkerFiledShowNum(); + logger.info("告警设置:checkType|"+alarm.getCheckType()+" setInfoId|"+alarm.getSetInfoId()+" markerShowNum|"+alarm.getMarkerFiledShowNum()+" marker|"+alarm.getMarker()); + if(markerShowNum!=null && markerShowNum>0 //若未指定标识字段,则从DC传递到NC的json字符串中markerShowNum的值为0 + && StringUtils.isNotBlank(marker)) { + String markerCurVal = sysData[markerShowNum - 1];//当前条详细监测数据的标识符 + String sperator = SysConfig.getStringVal("alarm.set.marker.separator", "|"); + if(StringUtils.isNotBlank(markerCurVal)) { + if(!(sperator+marker.trim()+sperator).toLowerCase().contains((sperator+markerCurVal.trim()+sperator).toLowerCase())) {//当前标识不在指定的标识里 + continue; + } + }else { + continue; + } + } + + if ("equals".equalsIgnoreCase(alarm.getPoliceSysmbols())) {//相同 + if(data.equals(alarm.getPoliceValue())){ + alarmFlag = true; + } + } else if ("include".equalsIgnoreCase(alarm.getPoliceSysmbols())) {//包含告警值内容 + if(data.contains(alarm.getPoliceValue())){ + alarmFlag = true; + } + } else if ("exclude".equalsIgnoreCase(alarm.getPoliceSysmbols())) {//不包含告警值内容 + if(!data.contains(alarm.getPoliceValue())){ + alarmFlag = true; + } + } else { + double result = Double.parseDouble(data) - Double.parseDouble(alarm.getPoliceValue()); + if ((">".equals(alarm.getPoliceSysmbols()) && result > 0) + || ("<".equals(alarm.getPoliceSysmbols()) && result < 0) + || ("=".equals(alarm.getPoliceSysmbols()) && result == 0) + || (">=".equals(alarm.getPoliceSysmbols()) && result >= 0) + || ("<=".equals(alarm.getPoliceSysmbols()) && result <=0) ) { + alarmFlag = true; + } + } + String sysmbol = getAlarmSymbol(alarm.getPoliceSysmbols(), alarmFlag); + if(alarmFlag){ + strs[0] += alarm.getShowNum() + "|";// 告警序列号 + strs[1] += alarm.getPoliceLevel() + "|"; //告警级别 + strs[2] += alarm.getPoliceValue() + "|"; //告警值 + //性能信息 + if(setInfo!=null && "process".equalsIgnoreCase(setInfo.getCheckTypeName())) {//如果是进程监测 +// strs[3] +="进程不存在 ";//如果不加\",则只显示进程不存,少一个字符,所以在最后加空格,这样就不会少显示一个字符了 + strs[3] +="i18n_client.GetInfoRun.processNotExists_n81i ";//如果不加\",则只显示进程不存,少一个字符,所以在最后加空格,这样就不会少显示一个字符了 +// strs[3] +="进程不存在(进程PID文件:"+setInfo.getProcessFile()+",进程搜索关键字:"+setInfo.getProcessSearchKeyCode()+")"; +// }else if(setInfo!=null && "disk".equalsIgnoreCase(setInfo.getCheckTypeName()) && "磁盘是否可写".equals(alarm.getFiledCommonts())){ + }else if(setInfo!=null && "disk".equalsIgnoreCase(setInfo.getCheckTypeName()) && "i18n_client.GetInfoRun.isDiskWriteAble_n81i".equals(alarm.getFiledCommonts())){ + strs[3] += alarm.getFiledCommonts()+":not writable;"; + }else { +// if(setInfo!=null && "disk".equalsIgnoreCase(setInfo.getCheckTypeName()) && "磁盘使用率(%)".equals(alarm.getFiledCommonts())){ + if(setInfo!=null && "disk".equalsIgnoreCase(setInfo.getCheckTypeName()) && "i18n_client.GetInfoRun.diskUsed_n81i".equals(alarm.getFiledCommonts())){ + diskUsageTime ++; + if("Linux".equals(System.getProperties().getProperty("os.name"))){ + diskUsageName+=sysData[0]+","; +// firstPerformData = diskUsageTime+"个磁盘使用率超过"+alarm.getPoliceValue()+"%:"+diskUsageName; + firstPerformData = diskUsageTime+"i18n_client.GetInfoRun.warning_n81i"+alarm.getPoliceValue()+"%:"+diskUsageName; + }else{ + diskUsageName+=sysData[0].substring(0,sysData[0].length()-2)+","; +// firstPerformData = diskUsageTime+"个磁盘使用率超过"+alarm.getPoliceValue()+"%:"+diskUsageName.substring(0,diskUsageName.length()-1); + firstPerformData = diskUsageTime+"i18n_client.GetInfoRun.warning_n81i"+alarm.getPoliceValue()+"%:"+diskUsageName.substring(0,diskUsageName.length()-1); + } + } +// if(setInfo!=null && "cpu".equalsIgnoreCase(setInfo.getCheckTypeName()) && "总的使用率(%)".equals(alarm.getFiledCommonts())){ + if(setInfo!=null && "cpu".equalsIgnoreCase(setInfo.getCheckTypeName()) && "i18n_client.GetInfoRun.ZongShiYongLv_n81i".equals(alarm.getFiledCommonts())){ + cpuUsageTime ++;//超过告警值得cpu数量 + cpuUsageName+=sysData[0]+","; +// firstPerformData = cpuUsageTime+"个CPU的使用率占"+alarm.getPoliceValue()+"%:"+cpuUsageName.substring(0,cpuUsageName.length()-1); + firstPerformData = cpuUsageTime+"i18n_client.GetInfoRun.cpuShiyonglv_n81i"+alarm.getPoliceValue()+"%:"+cpuUsageName.substring(0,cpuUsageName.length()-1); + } +// strs[3] += alarm.getFiledCommonts()+":" +// + sysData[alarm.getShowNum() - 1] +// + "("+alarm.getPoliceUnit()+") " + sysmbol + "告警值" +// + alarm.getPoliceValue() +// + "("+alarm.getPoliceUnit()+") " + " 不正常;"; + strs[3] += alarm.getFiledCommonts()+":" + + sysData[alarm.getShowNum() - 1] + + "("+alarm.getPoliceUnit()+") " + sysmbol + "i18n_client.GetInfoRun.warningValue_n81i" + + alarm.getPoliceValue() + + "("+alarm.getPoliceUnit()+") " + " i18n_client.GetInfoRun.abnormal_n81i;"; + } + + //2011-09-29 添加了连续几次达到告警值后主动告警,恢复正常后发送恢复信息 + //2013-03-26 添加了告警状态控制是否立刻主动告警,如果已经告警则后期不发送告警信息。 + //alarmHandler(alarm, strs[3]); + + if (maxAlarmLevel > alarm.getPoliceLevel()) {// 保留本次最高告警级别,值越小级别越高 + maxAlarmLevel = alarm.getPoliceLevel(); + maxShowNum = alarm.getShowNum()+""; + } + + }else{ +// if(setInfo!=null && "disk".equalsIgnoreCase(setInfo.getCheckTypeName()) && "磁盘是否可写".equals(alarm.getFiledCommonts())){ +// strs[3] += alarm.getFiledCommonts()+":可写;"; + if(setInfo!=null && "disk".equalsIgnoreCase(setInfo.getCheckTypeName()) && "i18n_client.GetInfoRun.isDiskWriteAble_n81i".equals(alarm.getFiledCommonts())){ + strs[3] += alarm.getFiledCommonts()+":i18n_client.GetInfoRun.writeAble_n81i;"; + }else{ + // 性能信息 + strs[3] += alarm.getFiledCommonts() + + sysData[alarm.getShowNum() - 1] + + alarm.getPoliceUnit() + sysmbol + "i18n_client.GetInfoRun.warningValue_n81i" + + alarm.getPoliceValue() + + alarm.getPoliceUnit() + " i18n_client.GetInfoRun.normal_n81i;"; + } + //对发送告警信息后,恢复正常的信息(为保证告警成对) + //2013-03-26 当告警恢复后发送恢复告警信息。 + //alarmRecovery(alarm, strs[3]); + + } + + }//for end + for (int i = 0; i < strs.length-1; i++) { + if (strs[i].length() > 0) { + strs[i] = strs[i].substring(0, strs[i].length() - 1); + } + } + strs[strs.length-2] = maxAlarmLevel + "";// 本次告警最高级别 + strs[strs.length-1] = maxShowNum ;// 本次告警最高级别对应的序列号showNum + return strs; + } + + private String getAlarmSymbol(String oldSymbol, boolean alarmFlag){ + String symbol = ""; + if(alarmFlag){ +// if(">".equals(oldSymbol)){ +// symbol = "大于"; +// }else if(">=".equals(oldSymbol)){ +// symbol = "超过"; +// }else if("<".equals(oldSymbol)){ +// symbol = "小于"; +// }else if("<=".equals(oldSymbol)){ +// symbol = "未超过"; +// }else if("=".equals(oldSymbol)){ +// symbol = "等于"; +// }else{ +// symbol = oldSymbol; +// } + if(">".equals(oldSymbol)){ + symbol = "i18n_client.GetInfoRun.gt_n81i"; + }else if(">=".equals(oldSymbol)){ + symbol = "i18n_client.GetInfoRun.out_n81i"; + }else if("<".equals(oldSymbol)){ + symbol = "i18n_client.GetInfoRun.lt_n81i"; + }else if("<=".equals(oldSymbol)){ + symbol = "i18n_client.GetInfoRun.in_n81i"; + }else if("=".equals(oldSymbol)){ + symbol = "i18n_client.GetInfoRun.eq_n81i"; + }else{ + symbol = oldSymbol; + } + }else{ +// if(">".equals(oldSymbol)){ +// symbol = "未超过"; +// }else if(">=".equals(oldSymbol)){ +// symbol = "小于"; +// }else if("<".equals(oldSymbol)){ +// symbol = "超过"; +// }else if("<=".equals(oldSymbol)){ +// symbol = "大于"; +// }else if("=".equals(oldSymbol)){ +// symbol = "不等于"; + if(">".equals(oldSymbol)){ + symbol = "i18n_client.GetInfoRun.in_n81i"; + }else if(">=".equals(oldSymbol)){ + symbol = "i18n_client.GetInfoRun.lt_n81i"; + }else if("<".equals(oldSymbol)){ + symbol = "i18n_client.GetInfoRun.out_n81i"; + }else if("<=".equals(oldSymbol)){ + symbol = "i18n_client.GetInfoRun.gt_n81i"; + }else if("=".equals(oldSymbol)){ + symbol = "i18n_client.GetInfoRun.notEquels_n81i"; + }else if("equals".equalsIgnoreCase(oldSymbol)){ + symbol = "not equals"; + }else if("include".equalsIgnoreCase(oldSymbol)){ + symbol = "exclude"; + }else if("exclude".equalsIgnoreCase(oldSymbol)){ + symbol = "include"; + } + } + return symbol; + } + + /*// 判断是否主动告警 + private void alarmHandler(AlarmInfo alarm, String alarmInfo){ + // 判断告警状态是否变化,主动告警 + synchronized (alarmStates) { + boolean isAlarm = false; + if(alarmStates.containsKey(alarm.getId())){ + isAlarm = alarmStates.get(alarm.getId()); + } + if(!isAlarm){ + alarmStates.put(alarm.getId(), true); + // 报警 + AlarmUtil.sendAlarmMsg(setInfo.getId(), + setInfo.getCheckTypeName(), + setInfo.getProcessIden(), new Date(), + new Date(), alarm.getPoliceLevel(), + Contants.DETECTION_STATUS_ABNORMAL, alarmInfo); + logger.debug("主动告警:" + alarmInfo); + logger.debug("------id=" + alarm.getId() + "---Comments="+alarm.getFiledCommonts()+"---val=-1"); + } + } + // 判断连续达到告警值的次数,达到一定次数,主动告警 + synchronized (alarmTimes) { + if(alarmTimes.containsKey(alarm.getId())){ + int alarmCnt = alarmTimes.get(alarm.getId()); + if(alarmCnt + 1 >= Contants.overAlarmValTimes){//连续几次达到告警值 + String alarmMsg = alarm.getFiledCommonts() + ", 连续" + (alarmCnt + 1) + "次达到告警值"; + AlarmUtil.sendAlarmMsg(setInfo.getId(), + setInfo.getCheckTypeName(), + setInfo.getProcessIden(), new Date(), + new Date(), alarm.getPoliceLevel(), + Contants.DETECTION_STATUS_ABNORMAL, alarmMsg); + logger.debug("主动告警:"+alarmMsg); + alarmTimes.put(alarm.getId(), -1); + + logger.debug("------id=" + alarm.getId() + "---Comments="+alarm.getFiledCommonts()+"---val=-1"); + }else if(alarmCnt > -1){ + alarmTimes.put(alarm.getId(), alarmCnt + 1); + logger.debug("------id=" + alarm.getId() + "---Comments="+alarm.getFiledCommonts()+"---val="+(alarmCnt + 1)); + } + }else{ + alarmTimes.put(alarm.getId(), 1); + logger.debug("---nokey---id=" + alarm.getId() + "---Comments="+alarm.getFiledCommonts()+"---val=1"); + } + } + } + // 判断是否恢复正常 + private void alarmRecovery(AlarmInfo alarm, String alarmInfo){ + // 判断是否告警状态,恢复正常 + synchronized (alarmStates) { + if(alarmStates.containsKey(alarm.getId())){ + boolean isAlarm = alarmStates.get(alarm.getId()); + if(isAlarm){ + alarmStates.put(alarm.getId(), false); + // 报警状态:恢复正常 + AlarmUtil.sendAlarmMsg(setInfo.getId(), + setInfo.getCheckTypeName(), + setInfo.getProcessIden(), new Date(), + new Date(), 99, Contants.DETECTION_STATUS_NORMAL, + alarmInfo); + logger.debug(alarmInfo + ", 恢复正常"); + logger.debug("------id=" + alarm.getId() + "---Comments="+alarm.getFiledCommonts()+"---val=0"); + } + } + } + // 判断是否连续几次达到告警值后主动告警,恢复正常 + synchronized (alarmTimes) { + if(alarmTimes.containsKey(alarm.getId())){ + if(alarmTimes.get(alarm.getId()) == -1){ + AlarmUtil.sendAlarmMsg(setInfo.getId(), + setInfo.getCheckTypeName(), + setInfo.getProcessIden(), new Date(), + new Date(), 99, Contants.DETECTION_STATUS_NORMAL, + alarm.getFiledCommonts() + ", 恢复正常"); + logger.debug(alarm.getFiledCommonts() + ", 恢复正常"); + } + alarmTimes.put(alarm.getId(), 0); + logger.debug("------id=" + alarm.getId() + "---Comments="+alarm.getFiledCommonts()+"---val=0"); + } + } + }*/ + + private String getUUID(){ + return Contants.AGENT_HOST_UUID + ""; //Utils.getLocalIp(); + } + // 检测时延(秒) + private String getCheckDelayTime(Date now){ + long val = System.currentTimeMillis() - now.getTime(); + return val/1000 + ""; + } + // 下一次检测时间 + private String getNextCheckTime(Date now){ + Calendar cal = Calendar.getInstance(); + cal.setTime(now); + cal.add(Calendar.MINUTE, setInfo.getCheckGap().intValue()); + return cal.getTimeInMillis() + ""; + } + // 服务监控开始时间 + private String getStartClientTime(){ + return this.startTime.getTime() + ""; + } + // 开机时间 + private String getStartComputerTime(){ + return SystemInfo.getStartComputerTime(); + } + + public SetInfo getSetInfo() { + return setInfo; + } + + public void setSetInfo(SetInfo setInfo) { + this.setInfo = setInfo; + } + + public List getAlarmInfos() { + return alarmInfos; + } + + public void setAlarmInfos(List alarmInfos) { + this.alarmInfos = alarmInfos; + } + + public String getFirstPerformData() { + return firstPerformData; + } + + public void setFirstPerformData(String firstPerformData) { + this.firstPerformData = firstPerformData; + } + +} diff --git a/src/com/nis/systeminfo/thread/NewPluginResultMerge.java b/src/com/nis/systeminfo/thread/NewPluginResultMerge.java new file mode 100644 index 0000000..900e26a --- /dev/null +++ b/src/com/nis/systeminfo/thread/NewPluginResultMerge.java @@ -0,0 +1,476 @@ +package com.nis.systeminfo.thread; + +import java.io.File; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; + +import org.apache.commons.lang.ArrayUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + +import com.nis.nmsclient.common.Common; +import com.nis.nmsclient.common.Contants; +import com.nis.nmsclient.common.SysConfig; +import com.nis.nmsclient.model.AlarmInfo; +import com.nis.nmsclient.model.SetInfo; +import com.nis.nmsclient.thread.alarm.AlarmUtil; +import com.nis.nmsclient.util.DateUtil; +import com.nis.nmsclient.util.FileWrUtil; + +public class NewPluginResultMerge { + + private static final Logger logger = Logger.getLogger(NewPluginResultMerge.class); + + private static final File srcRootDir = new File(Contants.localTempDataIncomingPath); + private static final File tarRootDir = new File(Contants.localDataFilePath); + + private static HashMap historyAlarmStateMap = new HashMap(); + private static HashMap historyAlarmTimesMap = new HashMap(); + + public void clearTmpFile(SetInfo setInfo) { + try { + String subDir = setInfo.getCheckTypeName() + "_" + setInfo.getProcessIden(); + File dir = new File(srcRootDir, subDir); + + if(!dir.exists()) { + dir.mkdirs(); // 临时目录不存在 + return; + } + + File[] results = dir.listFiles(); + for (File file : results) { + file.delete(); + } + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + } + + public void merge(SetInfo setInfo) { + try { + logger.debug("合并临时结果文件开始 ~~~~~~~"); + String subDir = setInfo.getCheckTypeName() + "_" + setInfo.getProcessIden(); + File dir = new File(srcRootDir, subDir); + File tarDir = new File(tarRootDir, subDir); + + /* + * 临时目录为空,当前检测未生成结果数据 + */ + if (!dir.exists() || dir.listFiles().length == 0) { + AlarmUtil.sendAlarmMsg(setInfo.getId(), setInfo.getCheckTypeName(), setInfo.getProcessIden(), +// new Date(), new Date(), 1, Contants.DETECTION_STATUS_FAILURE, "监测数据未生成"); + new Date(), new Date(), 1, Contants.DETECTION_STATUS_FAILURE, "i18n_client.NewPluginResultMerge.detecateData_n81i"); + return; + } + + // 监测信息报警相关信息 + System.out.println(Common.detecAlarmInfoMap); + List alarmInfoList = Common.getDetecAlarmInfo(setInfo.getId()); + + // 获取临时结果文件 + File srcFile = dir.listFiles()[0]; + // 从文件名获取监测时间毫秒数(YYYYMMDDhhmmss.tmp) + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.YEAR, Integer.parseInt(srcFile.getName().substring(0, 4))); + cal.set(Calendar.MONTH, Integer.parseInt(srcFile.getName().substring(4, 6)) - 1); + cal.set(Calendar.DATE, Integer.parseInt(srcFile.getName().substring(6, 8))); + cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(srcFile.getName().substring(8, 10))); + cal.set(Calendar.MINUTE, Integer.parseInt(srcFile.getName().substring(10, 12))); + cal.set(Calendar.SECOND, Integer.parseInt(srcFile.getName().substring(12, 14))); + + Long detecTime = cal.getTimeInMillis(); + Date writeDate = new Date(detecTime); // 临时文件写入时间 + + //读取临时结果文件 + List lines = FileWrUtil.csvFileParser(srcFile, Contants.charset); + + /* 临时数据文件新格式形式 + * line1: 监测时延(秒),尝试次数,状态信息(描述信息),字段1,字段2,··· + * + * 旧格式转新格式 + */ + if(lines.size() == 1 && lines.get(0).length > 3) { + String[] data = lines.get(0); + lines.clear(); + lines.add((String[]) ArrayUtils.subarray(data, 0, 3)); + lines.add(new String[]{"details","1"}); + lines.add((String[]) ArrayUtils.subarray(data, 3, data.length)); + } + + /* + * 临时数据文件新格式形式 + * line1: 监测时延(秒),尝试次数,状态信息(描述信息) + * line2: details,具体数据条数 + * line3: 监测字段1,监测字段2,··· + * ··· ··· ··· + * + * 任务执行失败状态判断(临时文件存在时,告警并删除临时文件): + * 1、公共信息不完整;2、无具体数据信息或具体数据信息为空 + */ + boolean execFail = false; + if(lines.size() < 1 || lines.get(0).length < 3) { // 公共信息不完整 + logger.info("预设监测 setId: " + setInfo.getId() + " > " + srcFile.getName() + ",公共信息不完整,监测执行错误"); + execFail = true; + } + if(lines.size() < 3) { // 无具体数据信息 + logger.info("预设监测 setId: " + setInfo.getId() + " > " + srcFile.getName() + ",无具体数据信息,监测执行错误"); + execFail = true; + } + if(lines.size() >= 3) { // 具体数据信息为空字段 + String detailStr = Arrays.toString(lines.get(1)); + String detailReg = "^\\[details,\\s*(\\d+)\\s*\\]$"; + if(detailStr.matches(detailReg)) { + int endNum = Integer.parseInt(detailStr.replaceAll(detailReg, "$1")); // details格式校验 + if (endNum < 1) { + logger.info("预设监测 setId: " + setInfo.getId() + " > " + srcFile.getName() + ",具体数据信息格式错误,监测执行错误"); + execFail = true; + } + for (int r = 0; r < endNum; r++) { + String[] sysData = lines.get(r + 2); + if (Arrays.toString(sysData).matches("^\\[[,|\\s]*\\]$")) { // 空字段 + logger.info("预设监测 setId: " + setInfo.getId() + " > " + srcFile.getName() + ",具体数据信息为空字段,监测执行错误"); + execFail = true; + } + } + } else { + logger.info("预设监测 setId: " + setInfo.getId() + " > " + srcFile.getName() + ",具体数据信息格式错误,监测执行错误"); + execFail = true; + } + } + if(execFail) { + historyAlarmStateMap.put(setInfo.getId(), true); // 数据状态不正常 + srcFile.delete(); // 删除错误临时文件,并告警 + AlarmUtil.sendAlarmMsg(setInfo.getId(), setInfo.getCheckTypeName(), setInfo.getProcessIden(), +// new Date(detecTime), new Date(detecTime), 1, Contants.DETECTION_STATUS_FAILURE, "监测数据未生成或数据格式错误"); + new Date(detecTime), new Date(detecTime), 1, Contants.DETECTION_STATUS_FAILURE, "i18n_client.NewPluginResultMerge.formatErr_n81i"); + return; + } + + + String checkDelayTime = lines.get(0)[0];// 检测时延(秒) + String checkTimes = lines.get(0)[1]; // 尝试次数 + String detectInfo = lines.get(0)[2]; // 状态信息(描述信息) + StringBuffer functionSb = new StringBuffer(); // 性能数据 + + // 执行状态,告警级别 + int totalStatus = Contants.DETECTION_STATUS_ABNORMAL; //监测信息不正常 + int totalAlarmLevel = 99; + String totalShowNum ="";//告警序列号,取告警级别高的showNum add by jinsj for 紧急告警 + if(lines.size() > 1) { + String[] detail = lines.get(1); + if("details".equalsIgnoreCase(detail[0]) && detail[1].trim().matches("\\d+")) { + int endNum = StringUtils.isBlank(detail[1])?0:Integer.parseInt(detail[1].trim()); + + if(endNum > 0) { // 详细信息条数大于0,且所有数据不超过告警值时,监测信息正常 + totalStatus = Contants.DETECTION_STATUS_NORMAL; // 监测信息正常 + + for (int r = 0; r < endNum; r++) { + String[] sysData = lines.get(r + 2); + String[] warninfos = getAlarmState(alarmInfoList, sysData); + String[] combine = new String[sysData.length + 3]; // 组合详细信息 + System.arraycopy(warninfos, 0, combine, 0, 3); + System.arraycopy(sysData, 0, combine, 3, sysData.length); + lines.set(r + 2, combine); + + if(StringUtils.isNotBlank(warninfos[4])) { + totalAlarmLevel = Integer.parseInt(warninfos[4]); + } + totalShowNum = warninfos[5]; + + if(StringUtils.isNotBlank(warninfos[0])) { + totalStatus = Contants.DETECTION_STATUS_ABNORMAL; // 监测信息不正常 + functionSb.append(warninfos[3] + "
"); // 组织性能数据 + } else { + if(StringUtils.isNotBlank(warninfos[3])) { + functionSb.append(warninfos[3] + "
"); // 组织性能数据 + } + } + } + } + } + } + + // 主动告警 + String totalAlarmInfo = null; + if(totalStatus == Contants.DETECTION_STATUS_NORMAL){ + historyAlarmStateMap.put(setInfo.getId(), false); + historyAlarmTimesMap.put(setInfo.getId(), 0); + + // 本次数据正常,看原本的状态:若是告警状态,则发送恢复通知;若是正常状态,则不变 + if(getHistoryAlarmState(setInfo.getId())){ + totalAlarmInfo = "【i18n_client.NewPluginResultMerge.totalAlarmInfo1_n81i】
" + functionSb.toString(); + } + + }else if(totalStatus == Contants.DETECTION_STATUS_ABNORMAL){//状态异常 + historyAlarmStateMap.put(setInfo.getId(), true); + historyAlarmTimesMap.put(setInfo.getId(), getHistoryAlarmTimes(setInfo.getId()) + 1); + + // 本次数据不正常,看原本的状态:若是正常状态,则发送告警,此主动告警也只有一次,除非监测恢复正常,之后又异常 + if(getHistoryAlarmTimes(setInfo.getId()) == 1) {//如果是进程监测 + totalAlarmInfo = "【i18n_client.NewPluginResultMerge.totalAlarmInfo2_n81i】
" + functionSb.toString(); + } + if(getHistoryAlarmTimes(setInfo.getId()) == Contants.overAlarmValTimes) {//若原本的状态是告警状态,则判断是否连续几次达到告警值,次数会一直累积,知道监测恢复正常,所以如果一直异常,则也只告警一次连续4次异常 + totalAlarmInfo = "【i18n_client.NewPluginResultMerge.totalAlarmInfo3_n81i】
" + functionSb.toString(); + } + } + if(totalAlarmInfo!=null){ + //2014-5-12 add:根据配置的参数,决定是否启用监测数据超过设定值时的主动告警 + Boolean activeAlarmStart = Contants.ACTIIVE_ALARM_START; + if(totalStatus == Contants.DETECTION_STATUS_NORMAL || //数据恢复主动告警 + (activeAlarmStart && totalStatus == Contants.DETECTION_STATUS_ABNORMAL)) { //数据异常主动告警 + AlarmUtil.sendAlarmMsg(setInfo.getId(), setInfo.getCheckTypeName(), setInfo.getProcessIden(), + new Date(), new Date(), totalAlarmLevel, totalStatus, totalAlarmInfo,totalShowNum); + } + } + + // 组织监测数据组织 + List dataList = new LinkedList(); + // 总数据 + String[] totalData = new String[12]; + int index = 0; + totalData[index++] = Contants.AGENT_HOST_UUID + ""; // UUID + totalData[index++] = setInfo.getId() + ""; // 监测设置ID + totalData[index++] = setInfo.getCheckTypeName(); // 监测类别 + totalData[index++] = setInfo.getProcessIden(); // 进程名称 + totalData[index++] = setInfo.getPlanCheckTime() + ""; // 监测服务启动时间 + totalData[index++] = checkDelayTime; // 检测时延(秒) + totalData[index++] = writeDate.getTime() + ""; // 本次检测时间 + totalData[index++] = checkTimes; // 尝试次数 + totalData[index++] = getNextCheckTime(writeDate, setInfo);// 下次计划监测时间 + totalData[index++] = totalStatus + "";// 执行状态是否成功是否正常 + totalData[index++] = detectInfo; // 状态信息(描述信息) + totalData[index++] = StringUtils.isBlank(functionSb.toString()) ? detectInfo : functionSb.toString();// 性能数据 + + dataList.add(totalData); + // 详细信息 + dataList.addAll(lines.subList(1, lines.size())); + + // 写入文件 + String fileName = DateUtil.getStingDate(DateUtil.YYYYMMDDHH24MMSS, writeDate) + ".csv"; + File tarFile1 = new File(tarDir, fileName + ".tp"); + FileWrUtil.csvFilePrinter(tarFile1, Contants.charset, dataList); + File tarFile2 = new File(tarDir, fileName); + if (tarFile2.exists()) + tarFile2.delete(); + tarFile1.renameTo(tarFile2); + srcFile.delete(); + + logger.info("生成监测结果文件:" + tarFile2.getParentFile().getName() + "/" + tarFile2.getName()); + + // 忽略NC停止时间内的监测周期 + // setInfo.setLastMergeDetecTime(detecTime); + setInfo.setLastMergeDetecTime(Math.max(detecTime, setInfo.getLastMergeDetecTime())); + + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + } + + // 下一次检测时间 + private String getNextCheckTime(Date now, SetInfo setInfo) { + Calendar cal = Calendar.getInstance(); + cal.setTime(now); + cal.add(Calendar.MINUTE, setInfo.getCheckGap().intValue()); + return cal.getTimeInMillis() + ""; + } + + /** + * 获取当前行告警信息 + * @param sysData + * @return + */ + private String[] getAlarmState(List alarmInfos, String[] sysData) { + // strs数组数据依次为:告警序列号、告警级别、告警值、性能数据、本次最高告警级别 + String[] strs = new String[] { "", "", "", "", "", "" }; + if (alarmInfos == null) { + return strs; + } + int maxAlarmLevel = 99; + String maxShowNum = ""; + for (AlarmInfo alarm : alarmInfos) { + if (sysData.length < alarm.getShowNum()) {// 得到的数据个数和告警列数比较 + continue; + } + String data = sysData[alarm.getShowNum() - 1]; + boolean alarmFlag = false; + + /** + * 2014-5-15 add: 1.指定了特定的标识: (1).当前标识非空:不在指定标识内,则不做告警判断;在,则做告警判断 + * (2).当前标识为空:空不在指定标识内,不做告警判断 2.未指定特定的标识:所有标识都进行告警判断 + */ + String marker = alarm.getMarker(); + // Integer markerShowNum = 1;//先默认取第一个 + Integer markerShowNum = alarm.getMarkerFiledShowNum(); + logger.info("告警设置:checkType|" + alarm.getCheckType() + " setInfoId|" + alarm.getSetInfoId() + + " markerShowNum|" + alarm.getMarkerFiledShowNum() + " marker|" + alarm.getMarker()); + if (markerShowNum != null && markerShowNum > 0 // 若未指定标识字段,则从DC传递到NC的json字符串中markerShowNum的值为0 + && StringUtils.isNotBlank(marker)) { + String markerCurVal = sysData[markerShowNum - 1];// 当前条详细监测数据的标识符 + String sperator = SysConfig.getStringVal("alarm.set.marker.separator", "|"); + if (StringUtils.isNotBlank(markerCurVal)) { + if (!(sperator + marker.trim() + sperator).toLowerCase().contains( + (sperator + markerCurVal.trim() + sperator).toLowerCase())) {// 当前标识不在指定的标识里 + continue; + } + } else { + continue; + } + } + + if ("equals".equalsIgnoreCase(alarm.getPoliceSysmbols())) {// 相同 + if (data.equals(alarm.getPoliceValue())) { + alarmFlag = true; + } + } else if ("include".equalsIgnoreCase(alarm.getPoliceSysmbols())) {// 包含告警值内容 + if (data.contains(alarm.getPoliceValue())) { + alarmFlag = true; + } + } else if ("exclude".equalsIgnoreCase(alarm.getPoliceSysmbols())) {// 不包含告警值内容 + if (!data.contains(alarm.getPoliceValue())) { + alarmFlag = true; + } + } else { + double result = Double.parseDouble(data) + - Double.parseDouble(alarm.getPoliceValue()); + if ((">".equals(alarm.getPoliceSysmbols()) && result > 0) + || ("<".equals(alarm.getPoliceSysmbols()) && result < 0) + || ("=".equals(alarm.getPoliceSysmbols()) && result == 0) + || (">=".equals(alarm.getPoliceSysmbols()) && result >= 0) + || ("<=".equals(alarm.getPoliceSysmbols()) && result <= 0)) { + alarmFlag = true; + } + } + + String sysmbol = getAlarmSymbol(alarm.getPoliceSysmbols(), alarmFlag); + if (alarmFlag) { + strs[0] += alarm.getShowNum() + "|";// 告警序列号 + strs[1] += alarm.getPoliceLevel() + "|"; // 告警级别 + strs[2] += alarm.getPoliceValue() + "|"; // 告警值 + // 性能信息 +// strs[3] += alarm.getFiledCommonts() + ":" +// + sysData[alarm.getShowNum() - 1] + "(" +// + alarm.getPoliceUnit() + ") " + sysmbol + "告警值" +// + alarm.getPoliceValue() + "(" + alarm.getPoliceUnit() +// + ") " + "不正常;"; + strs[3] += alarm.getFiledCommonts() + ":" + + sysData[alarm.getShowNum() - 1] + "(" + + alarm.getPoliceUnit() + ") " + sysmbol + "i18n_client.NewPluginResultMerge.warningValue_n81i" + + alarm.getPoliceValue() + "(" + alarm.getPoliceUnit() + + ") " + "i18n_client.NewPluginResultMerge.abnormal_n81i;"; + } else { + // 性能信息 +// strs[3] += alarm.getFiledCommonts() + ":" +// + sysData[alarm.getShowNum() - 1] + "(" +// + alarm.getPoliceUnit() + ") " + sysmbol + "告警值" +// + alarm.getPoliceValue() + "(" + alarm.getPoliceUnit() +// + ") " + "正常;"; + strs[3] += alarm.getFiledCommonts() + ":" + + sysData[alarm.getShowNum() - 1] + "(" + + alarm.getPoliceUnit() + ") " + sysmbol + "i18n_client.NewPluginResultMerge.warningValue_n81i" + + alarm.getPoliceValue() + "(" + alarm.getPoliceUnit() + + ") " + "i18n_client.NewPluginResultMerge.normal_n81i;"; + } + + // 2011-09-29 添加了连续几次达到告警值后主动告警,恢复正常后发送恢复信息 + // 2013-03-26 添加了告警状态控制是否立刻主动告警,如果已经告警则后期不发送告警信息。 + if (maxAlarmLevel > alarm.getPoliceLevel()) {// 保留本次最高告警级别,值越小级别越高 + maxAlarmLevel = alarm.getPoliceLevel(); + maxShowNum = alarm.getShowNum() + ""; + } + + }// for end + for (int i = 0; i < strs.length - 1; i++) { + if (strs[i].length() > 0) { + strs[i] = strs[i].substring(0, strs[i].length() - 1); + } + } + strs[strs.length - 2] = maxAlarmLevel + "";// 本次告警最高级别 + strs[strs.length - 1] = maxShowNum;// 本次告警最高级别对应的序列号showNum + return strs; + } + + private String getAlarmSymbol(String oldSymbol, boolean alarmFlag) { + String symbol = ""; +// if (alarmFlag) { +// if (">".equals(oldSymbol)) { +// symbol = "大于"; +// } else if (">=".equals(oldSymbol)) { +// symbol = "超过"; +// } else if ("<".equals(oldSymbol)) { +// symbol = "小于"; +// } else if ("<=".equals(oldSymbol)) { +// symbol = "未超过"; +// } else if ("=".equals(oldSymbol)) { +// symbol = "等于"; +// } else { +// symbol = oldSymbol; +// } +// } else { +// if (">".equals(oldSymbol)) { +// symbol = "未超过"; +// } else if (">=".equals(oldSymbol)) { +// symbol = "小于"; +// } else if ("<".equals(oldSymbol)) { +// symbol = "超过"; +// } else if ("<=".equals(oldSymbol)) { +// symbol = "大于"; +// } else if ("=".equals(oldSymbol)) { +// symbol = "不等于"; +// } else if ("equals".equalsIgnoreCase(oldSymbol)) { +// symbol = "not equals"; +// } else if ("include".equalsIgnoreCase(oldSymbol)) { +// symbol = "exclude"; +// } else if ("exclude".equalsIgnoreCase(oldSymbol)) { +// symbol = "include"; +// } +// } + if (alarmFlag) { + if (">".equals(oldSymbol)) { + symbol = "i18n_client.NewPluginResultMerge.gt_n81i"; + } else if (">=".equals(oldSymbol)) { + symbol = "i18n_client.NewPluginResultMerge.out_n81i"; + } else if ("<".equals(oldSymbol)) { + symbol = "i18n_client.NewPluginResultMerge.lt_n81i"; + } else if ("<=".equals(oldSymbol)) { + symbol = "i18n_client.NewPluginResultMerge.in_n81i"; + } else if ("=".equals(oldSymbol)) { + symbol = "i18n_client.NewPluginResultMerge.eq_n81i"; + } else { + symbol = oldSymbol; + } + } else { + if (">".equals(oldSymbol)) { + symbol = "i18n_client.NewPluginResultMerge.in_n81i"; + } else if (">=".equals(oldSymbol)) { + symbol = "i18n_client.NewPluginResultMerge.lt_n81i"; + } else if ("<".equals(oldSymbol)) { + symbol = "i18n_client.NewPluginResultMerge.out_n81i"; + } else if ("<=".equals(oldSymbol)) { + symbol = "i18n_client.NewPluginResultMerge.gt_n81i"; + } else if ("=".equals(oldSymbol)) { + symbol = "i18n_client.GetInfoRun.notEquels_n81i"; + } else if ("equals".equalsIgnoreCase(oldSymbol)) { + symbol = "not equals"; + } else if ("include".equalsIgnoreCase(oldSymbol)) { + symbol = "exclude"; + } else if ("exclude".equalsIgnoreCase(oldSymbol)) { + symbol = "include"; + } + } + return symbol; + } + + private boolean getHistoryAlarmState(Long setInfoId) { + Boolean alarmState = historyAlarmStateMap.get(setInfoId); + return (alarmState != null && alarmState == true); + } + + private int getHistoryAlarmTimes(Long setInfoId) { + Integer alarmTimes = historyAlarmTimesMap.get(setInfoId); + return (alarmTimes != null ? alarmTimes : 0); + } +} diff --git a/src/com/nis/systeminfo/thread/PluginResultMerge.java b/src/com/nis/systeminfo/thread/PluginResultMerge.java new file mode 100644 index 0000000..9d9d245 --- /dev/null +++ b/src/com/nis/systeminfo/thread/PluginResultMerge.java @@ -0,0 +1,451 @@ +package com.nis.systeminfo.thread; + +import java.io.File; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Collection; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + +import com.nis.nmsclient.NmsClient; +import com.nis.nmsclient.common.Common; +import com.nis.nmsclient.common.Contants; +import com.nis.nmsclient.common.SysConfig; +import com.nis.nmsclient.model.AlarmInfo; +import com.nis.nmsclient.model.SetInfo; +import com.nis.nmsclient.thread.alarm.AlarmUtil; +import com.nis.nmsclient.util.DateUtil; +import com.nis.nmsclient.util.FileWrUtil; + +/** + * 临时文件的合并过程替换为NewPluginResultMerge + */ +@Deprecated +public class PluginResultMerge { + + private static final Logger logger = Logger.getLogger(PluginResultMerge.class); + + private static final File srcRootDir = new File(Contants.localTempDataIncomingPath); + private static final File tarRootDir = new File(Contants.localDataFilePath); + + private static HashMap historyAlarmStateMap = new HashMap(); + private static HashMap historyAlarmTimesMap = new HashMap(); + + public void merge() { + try { + logger.debug("合并临时结果文件开始 ~~~~~~~"); + + Collection setInfos = Common.getPluginDetecSetInfos(); + System.out.println(setInfos.size()); + for (SetInfo setInfo : setInfos) { + String subDir = setInfo.getCheckTypeName() + "_" + setInfo.getProcessIden(); + File dir = new File(srcRootDir, subDir); + File tarDir = new File(tarRootDir, subDir); + + if (!dir.exists() || dir.listFiles().length == 0) { + continue; + } + + // 监测信息报警相关信息 + System.out.println(Common.detecAlarmInfoMap); + List alarmInfoList = Common.getDetecAlarmInfo(setInfo.getId()); + + // 相邻的连个结果文件超过两个监测周期时,该时间段内出现未生成数据结果的周期 + Long period = setInfo.getCheckGap() * (60 * 1000); // millisecond + Long detecTimeout = period * 2; + + File[] results = dir.listFiles(); + Arrays.sort(results, new Comparator() { // 同一类结果文件按按时间先后排序 + public int compare(File f1, File f2) { + return f1.getName().compareTo(f2.getName()); + } + }); + + for (File srcFile : results) { + // 从文件名获取监测时间毫秒数(YYYYMMDDhhmmss.tmp) + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.YEAR, Integer.parseInt(srcFile.getName().substring(0, 4))); + cal.set(Calendar.MONTH, Integer.parseInt(srcFile.getName().substring(4, 6)) - 1); + cal.set(Calendar.DATE, Integer.parseInt(srcFile.getName().substring(6, 8))); + cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(srcFile.getName().substring(8, 10))); + cal.set(Calendar.MINUTE, Integer.parseInt(srcFile.getName().substring(10, 12))); + cal.set(Calendar.SECOND, Integer.parseInt(srcFile.getName().substring(12, 14))); + + Long detecTime = cal.getTimeInMillis(); + Date writeDate = new Date(detecTime); // 临时文件写入时间 + + while (setInfo.getLastMergeDetecTime() + detecTimeout < detecTime) { + // 存在未生成数据结果的监测周期(每个周期记录一次) + historyAlarmStateMap.put(setInfo.getId(), true); // 数据状态不正常 + + // 未生成监测数据(主动报警AlarmThread连续四次未生成监测数据报警) + AlarmUtil.sendAlarmMsg(setInfo.getId(), setInfo.getCheckTypeName(), setInfo.getProcessIden(), +// new Date(detecTime), new Date(detecTime), 1, Contants.DETECTION_STATUS_FAILURE, "监测数据未生成"); + new Date(detecTime), new Date(detecTime), 1, Contants.DETECTION_STATUS_FAILURE, "i18n_client.NewPluginResultMerge.detecateData_n81i"); + + // TODO 存在主动告警发送延时问题,可能会有多次告警连续发送 + setInfo.setLastMergeDetecTime(setInfo.getLastMergeDetecTime() + period); + } + + //读取临时结果文件 + List lines = FileWrUtil.csvFileParser(srcFile, Contants.charset); + + /* + * 任务执行失败状态判断(临时文件存在时,告警并删除临时文件): + * 1、公共信息不完整;2、无具体数据信息或具体数据信息为空 + */ + boolean execFail = false; + if(lines.size() < 1 || lines.get(0).length < 3) { // 公共信息不完整 + logger.info("预设监测 setId: " + setInfo.getId() + " > " + srcFile.getName() + ",公共信息不完整,监测执行错误"); + execFail = true; + } + if(lines.size() < 3) { // 无具体数据信息 + logger.info("预设监测 setId: " + setInfo.getId() + " > " + srcFile.getName() + ",无具体数据信息,监测执行错误"); + execFail = true; + } + if(lines.size() >= 3) { // 具体数据信息为空字段 + String detailStr = Arrays.toString(lines.get(1)); + String detailReg = "^\\[details, (\\d+)\\]$"; + if(detailStr.matches(detailReg)) { + int endNum = Integer.parseInt(detailStr.replaceAll(detailReg, "$1")); // details格式校验 + if (endNum < 1) { + logger.info("预设监测 setId: " + setInfo.getId() + " > " + srcFile.getName() + ",具体数据信息格式错误,监测执行错误"); + execFail = true; + } + for (int r = 0; r < endNum; r++) { + String[] sysData = lines.get(r + 2); + if (Arrays.toString(sysData).matches("^\\[[,|\\s]*\\]$")) { // 空字段 + logger.info("预设监测 setId: " + setInfo.getId() + " > " + srcFile.getName() + ",具体数据信息为空字段,监测执行错误"); + execFail = true; + } + } + } else { + logger.info("预设监测 setId: " + setInfo.getId() + " > " + srcFile.getName() + ",具体数据信息格式错误,监测执行错误"); + execFail = true; + } + } + if(execFail) { + historyAlarmStateMap.put(setInfo.getId(), true); // 数据状态不正常 + srcFile.delete(); // 删除错误临时文件,并告警 + AlarmUtil.sendAlarmMsg(setInfo.getId(), setInfo.getCheckTypeName(), setInfo.getProcessIden(), +// new Date(detecTime), new Date(detecTime), 1, Contants.DETECTION_STATUS_FAILURE, "监测数据未生成"); + new Date(detecTime), new Date(detecTime), 1, Contants.DETECTION_STATUS_FAILURE, "i18n_client.NewPluginResultMerge.detecateData_n81i"); + continue; + } + + + String checkDelayTime = lines.get(0)[0];// 检测时延(秒) + String checkTimes = lines.get(0)[1]; // 尝试次数 + String detectInfo = lines.get(0)[2]; // 状态信息(描述信息) + StringBuffer functionSb = new StringBuffer(); // 性能数据 + + // 执行状态,告警级别 + int totalStatus = Contants.DETECTION_STATUS_ABNORMAL; //监测信息不正常 + int totalAlarmLevel = 99; + String totalShowNum ="";//告警序列号,取告警级别高的showNum add by jinsj for 紧急告警 + if(lines.size() > 1) { + String[] detail = lines.get(1); + if("details".equalsIgnoreCase(detail[0]) && detail[1].trim().matches("\\d+")) { + int endNum = StringUtils.isBlank(detail[1])?0:Integer.parseInt(detail[1].trim()); + + if(endNum > 0) { // 详细信息条数大于0,且所有数据不超过告警值时,监测信息正常 + totalStatus = Contants.DETECTION_STATUS_NORMAL; // 监测信息正常 + + for (int r = 0; r < endNum; r++) { + String[] sysData = lines.get(r + 2); + String[] warninfos = getAlarmState(alarmInfoList, sysData); + String[] combine = new String[sysData.length + 3]; // 组合详细信息 + System.arraycopy(warninfos, 0, combine, 0, 3); + System.arraycopy(sysData, 0, combine, 3, sysData.length); + lines.set(r + 2, combine); + + totalAlarmLevel = Integer.parseInt(warninfos[4]); + totalShowNum = warninfos[5]; + + if(StringUtils.isNotBlank(warninfos[0])) { + totalStatus = Contants.DETECTION_STATUS_ABNORMAL; // 监测信息不正常 + functionSb.append(warninfos[3] + "
"); // 组织性能数据 + } else { + if(StringUtils.isNotBlank(warninfos[3])) { + functionSb.append(warninfos[3] + "
"); // 组织性能数据 + } + } + } + } + } + } + + // 主动告警 + String totalAlarmInfo = null; + if(totalStatus == Contants.DETECTION_STATUS_NORMAL){ + historyAlarmStateMap.put(setInfo.getId(), false); + historyAlarmTimesMap.put(setInfo.getId(), 0); + + // 本次数据正常,看原本的状态:若是告警状态,则发送恢复通知;若是正常状态,则不变 + if(getHistoryAlarmState(setInfo.getId())){ + totalAlarmInfo = "【i18n_client.NewPluginResultMerge.totalAlarmInfo1_n81i】
" + functionSb.toString(); + } + + }else if(totalStatus == Contants.DETECTION_STATUS_ABNORMAL){//状态异常 + historyAlarmStateMap.put(setInfo.getId(), true); + historyAlarmTimesMap.put(setInfo.getId(), getHistoryAlarmTimes(setInfo.getId()) + 1); + + // 本次数据不正常,看原本的状态:若是正常状态,则发送告警,此主动告警也只有一次,除非监测恢复正常,之后又异常 + if(getHistoryAlarmTimes(setInfo.getId()) == 1) {//如果是进程监测 + totalAlarmInfo = "【i18n_client.NewPluginResultMerge.totalAlarmInfo2_n81i】
" + functionSb.toString(); + } + if(getHistoryAlarmTimes(setInfo.getId()) == Contants.overAlarmValTimes) {//若原本的状态是告警状态,则判断是否连续几次达到告警值,次数会一直累积,知道监测恢复正常,所以如果一直异常,则也只告警一次连续4次异常 + totalAlarmInfo = "【i18n_client.NewPluginResultMerge.totalAlarmInfo3_n81i】
" + functionSb.toString(); + } + } + if(totalAlarmInfo!=null){ + //2014-5-12 add:根据配置的参数,决定是否启用监测数据超过设定值时的主动告警 + Boolean activeAlarmStart = Contants.ACTIIVE_ALARM_START; + if(totalStatus == Contants.DETECTION_STATUS_NORMAL || //数据恢复主动告警 + (activeAlarmStart && totalStatus == Contants.DETECTION_STATUS_ABNORMAL)) { //数据异常主动告警 + AlarmUtil.sendAlarmMsg(setInfo.getId(), setInfo.getCheckTypeName(), setInfo.getProcessIden(), + new Date(), new Date(), totalAlarmLevel, totalStatus, totalAlarmInfo,totalShowNum); + } + } + + // 组织监测数据组织 + List dataList = new LinkedList(); + // 总数据 + String[] totalData = new String[12]; + int index = 0; + totalData[index++] = Contants.AGENT_HOST_UUID + ""; // UUID + totalData[index++] = setInfo.getId() + ""; // 监测设置ID + totalData[index++] = setInfo.getCheckTypeName(); // 监测类别 + totalData[index++] = setInfo.getProcessIden(); // 进程名称 + totalData[index++] = setInfo.getPlanCheckTime() + ""; // 监测服务启动时间 + totalData[index++] = checkDelayTime; // 检测时延(秒) + totalData[index++] = writeDate.getTime() + ""; // 本次检测时间 + totalData[index++] = checkTimes; // 尝试次数 + totalData[index++] = getNextCheckTime(writeDate, setInfo);// 下次计划监测时间 + totalData[index++] = totalStatus + "";// 执行状态是否成功是否正常 + totalData[index++] = detectInfo; // 状态信息(描述信息) + totalData[index++] = StringUtils.isBlank(functionSb.toString()) ? detectInfo : functionSb.toString();// 性能数据 + + dataList.add(totalData); + // 详细信息 + dataList.addAll(lines.subList(1, lines.size())); + + // 写入文件 + String fileName = DateUtil.getStingDate(DateUtil.YYYYMMDDHH24MMSS, writeDate) + ".csv"; + File tarFile1 = new File(tarDir, fileName + ".tp"); + FileWrUtil.csvFilePrinter(tarFile1, Contants.charset, dataList); + File tarFile2 = new File(tarDir, fileName); + if (tarFile2.exists()) + tarFile2.delete(); + tarFile1.renameTo(tarFile2); + srcFile.delete(); + + logger.info("生成监测结果文件:" + tarFile2.getParentFile().getName() + "/" + tarFile2.getName()); + + // 忽略NC停止时间内的监测周期 + // setInfo.setLastMergeDetecTime(detecTime); + setInfo.setLastMergeDetecTime(Math.max(detecTime, setInfo.getLastMergeDetecTime())); + } + + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + logger.debug("合并临时结果文件结束 ~~~~~~~"); + } + } + + // 下一次检测时间 + private String getNextCheckTime(Date now, SetInfo setInfo) { + Calendar cal = Calendar.getInstance(); + cal.setTime(now); + cal.add(Calendar.MINUTE, setInfo.getCheckGap().intValue()); + return cal.getTimeInMillis() + ""; + } + + public static void main(String[] args) { + NmsClient client = new NmsClient(); + client.initDetecConfig(); + for (SetInfo setInfo : client.setInfos) { + Common.putPluginDetecSetInfo(setInfo.getId(), setInfo); + } + new PluginResultMerge().merge(); + } + + /** + * 获取当前行告警信息 + * @param sysData + * @return + */ + private String[] getAlarmState(List alarmInfos, String[] sysData) { + // strs数组数据依次为:告警序列号、告警级别、告警值、性能数据、本次最高告警级别 + String[] strs = new String[] { "", "", "", "", "", "" }; + if (alarmInfos == null) { + return strs; + } + int maxAlarmLevel = 99; + String maxShowNum = ""; + for (AlarmInfo alarm : alarmInfos) { + if (sysData.length < alarm.getShowNum()) {// 得到的数据个数和告警列数比较 + continue; + } + String data = sysData[alarm.getShowNum() - 1]; + boolean alarmFlag = false; + + /** + * 2014-5-15 add: 1.指定了特定的标识: (1).当前标识非空:不在指定标识内,则不做告警判断;在,则做告警判断 + * (2).当前标识为空:空不在指定标识内,不做告警判断 2.未指定特定的标识:所有标识都进行告警判断 + */ + String marker = alarm.getMarker(); + // Integer markerShowNum = 1;//先默认取第一个 + Integer markerShowNum = alarm.getMarkerFiledShowNum(); + logger.info("告警设置:checkType|" + alarm.getCheckType() + " setInfoId|" + alarm.getSetInfoId() + + " markerShowNum|" + alarm.getMarkerFiledShowNum() + " marker|" + alarm.getMarker()); + if (markerShowNum != null && markerShowNum > 0 // 若未指定标识字段,则从DC传递到NC的json字符串中markerShowNum的值为0 + && StringUtils.isNotBlank(marker)) { + String markerCurVal = sysData[markerShowNum - 1];// 当前条详细监测数据的标识符 + String sperator = SysConfig.getStringVal("alarm.set.marker.separator", "|"); + if (StringUtils.isNotBlank(markerCurVal)) { + if (!(sperator + marker.trim() + sperator).toLowerCase().contains( + (sperator + markerCurVal.trim() + sperator).toLowerCase())) {// 当前标识不在指定的标识里 + continue; + } + } else { + continue; + } + } + + if ("equals".equalsIgnoreCase(alarm.getPoliceSysmbols())) {// 相同 + if (data.equals(alarm.getPoliceValue())) { + alarmFlag = true; + } + } else if ("include".equalsIgnoreCase(alarm.getPoliceSysmbols())) {// 包含告警值内容 + if (data.contains(alarm.getPoliceValue())) { + alarmFlag = true; + } + } else if ("exclude".equalsIgnoreCase(alarm.getPoliceSysmbols())) {// 不包含告警值内容 + if (!data.contains(alarm.getPoliceValue())) { + alarmFlag = true; + } + } else { + double result = Double.parseDouble(data) + - Double.parseDouble(alarm.getPoliceValue()); + if ((">".equals(alarm.getPoliceSysmbols()) && result > 0) + || ("<".equals(alarm.getPoliceSysmbols()) && result < 0) + || ("=".equals(alarm.getPoliceSysmbols()) && result == 0) + || (">=".equals(alarm.getPoliceSysmbols()) && result >= 0) + || ("<=".equals(alarm.getPoliceSysmbols()) && result <= 0)) { + alarmFlag = true; + } + } + + String sysmbol = getAlarmSymbol(alarm.getPoliceSysmbols(), alarmFlag); + if (alarmFlag) { + strs[0] += alarm.getShowNum() + "|";// 告警序列号 + strs[1] += alarm.getPoliceLevel() + "|"; // 告警级别 + strs[2] += alarm.getPoliceValue() + "|"; // 告警值 + // 性能信息 +// strs[3] += alarm.getFiledCommonts() + ":" +// + sysData[alarm.getShowNum() - 1] + "(" +// + alarm.getPoliceUnit() + ") " + sysmbol + "告警值" +// + alarm.getPoliceValue() + "(" + alarm.getPoliceUnit() +// + ") " + "不正常;"; + strs[3] += alarm.getFiledCommonts() + ":" + + sysData[alarm.getShowNum() - 1] + "(" + + alarm.getPoliceUnit() + ") " + sysmbol + "i18n_client.NewPluginResultMerge.warningValue_n81i" + + alarm.getPoliceValue() + "(" + alarm.getPoliceUnit() + + ") " + "i18n_client.NewPluginResultMerge.abnormal_n81i;"; + } else { + // 性能信息 + strs[3] += alarm.getFiledCommonts() + ":" + + sysData[alarm.getShowNum() - 1] + "(" + + alarm.getPoliceUnit() + ") " + sysmbol + "i18n_client.NewPluginResultMerge.warningValue_n81i" + + alarm.getPoliceValue() + "(" + alarm.getPoliceUnit() + + ") " + "i18n_client.NewPluginResultMerge.normal_n81i;"; + } + + // 2011-09-29 添加了连续几次达到告警值后主动告警,恢复正常后发送恢复信息 + // 2013-03-26 添加了告警状态控制是否立刻主动告警,如果已经告警则后期不发送告警信息。 + if (maxAlarmLevel > alarm.getPoliceLevel()) {// 保留本次最高告警级别,值越小级别越高 + maxAlarmLevel = alarm.getPoliceLevel(); + maxShowNum = alarm.getShowNum() + ""; + } + + }// for end + for (int i = 0; i < strs.length - 1; i++) { + if (strs[i].length() > 0) { + strs[i] = strs[i].substring(0, strs[i].length() - 1); + } + } + strs[strs.length - 2] = maxAlarmLevel + "";// 本次告警最高级别 + strs[strs.length - 1] = maxShowNum;// 本次告警最高级别对应的序列号showNum + return strs; + } + + private String getAlarmSymbol(String oldSymbol, boolean alarmFlag) { + String symbol = ""; + if (alarmFlag) { +// if (">".equals(oldSymbol)) { +// symbol = "大于"; +// } else if (">=".equals(oldSymbol)) { +// symbol = "超过"; +// } else if ("<".equals(oldSymbol)) { +// symbol = "小于"; +// } else if ("<=".equals(oldSymbol)) { +// symbol = "未超过"; +// } else if ("=".equals(oldSymbol)) { +// symbol = "等于"; +// } else { +// symbol = oldSymbol; +// } + if (">".equals(oldSymbol)) { + symbol = "i18n_client.NewPluginResultMerge.gt_n81i"; + } else if (">=".equals(oldSymbol)) { + symbol = "i18n_client.NewPluginResultMerge.out_n81i"; + } else if ("<".equals(oldSymbol)) { + symbol = "i18n_client.NewPluginResultMerge.lt_n81i"; + } else if ("<=".equals(oldSymbol)) { + symbol = "i18n_client.NewPluginResultMerge.in_n81i"; + } else if ("=".equals(oldSymbol)) { + symbol = "i18n_client.NewPluginResultMerge.eq_n81i"; + } else { + symbol = oldSymbol; + } + } else { + if (">".equals(oldSymbol)) { + symbol = "i18n_client.NewPluginResultMerge.in_n81i"; + } else if (">=".equals(oldSymbol)) { + symbol = "i18n_client.NewPluginResultMerge.lt_n81i"; + } else if ("<".equals(oldSymbol)) { + symbol = "i18n_client.NewPluginResultMerge.out_n81i"; + } else if ("<=".equals(oldSymbol)) { + symbol = "i18n_client.NewPluginResultMerge.gt_n81i"; + } else if ("=".equals(oldSymbol)) { + symbol = "i18n_client.GetInfoRun.notEquels_n81i"; + } else if ("equals".equalsIgnoreCase(oldSymbol)) { + symbol = "not equals"; + } else if ("include".equalsIgnoreCase(oldSymbol)) { + symbol = "exclude"; + } else if ("exclude".equalsIgnoreCase(oldSymbol)) { + symbol = "include"; + } + } + return symbol; + } + + private boolean getHistoryAlarmState(Long setInfoId) { + Boolean alarmState = historyAlarmStateMap.get(setInfoId); + return (alarmState != null && alarmState == true); + } + + private int getHistoryAlarmTimes(Long setInfoId) { + Integer alarmTimes = historyAlarmTimesMap.get(setInfoId); + return (alarmTimes != null ? alarmTimes : 0); + } +} diff --git a/src/de/innosystec/unrar/unpack/Unpack.java b/src/de/innosystec/unrar/unpack/Unpack.java new file mode 100644 index 0000000..07555e0 --- /dev/null +++ b/src/de/innosystec/unrar/unpack/Unpack.java @@ -0,0 +1,1057 @@ +/* + * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. + * Original author: Edmund Wagner + * Creation date: 31.05.2007 + * + * Source: $HeadURL$ + * Last changed: $LastChangedDate$ + * + * the unrar licence applies to all junrar source and binary distributions + * you are not allowed to use this source to re-create the RAR compression algorithm + * + * Here some html entities which can be used for escaping javadoc tags: + * "&": "&" or "&" + * "<": "<" or "<" + * ">": ">" or ">" + * "@": "@" + */ +package de.innosystec.unrar.unpack; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Vector; + +import de.innosystec.unrar.exception.RarException; +import de.innosystec.unrar.unpack.decode.Compress; +import de.innosystec.unrar.unpack.ppm.BlockTypes; +import de.innosystec.unrar.unpack.ppm.ModelPPM; +import de.innosystec.unrar.unpack.ppm.SubAllocator; +import de.innosystec.unrar.unpack.vm.BitInput; +import de.innosystec.unrar.unpack.vm.RarVM; +import de.innosystec.unrar.unpack.vm.VMPreparedProgram; + +/** + * DOCUMENT ME + * + * @author $LastChangedBy$ + * @version $LastChangedRevision$ + */ +public final class Unpack extends Unpack20 { + + private final ModelPPM ppm = new ModelPPM(); + + private int ppmEscChar; + + private RarVM rarVM = new RarVM(); + + /* Filters code, one entry per filter */ + private List filters = new ArrayList(); + + /* Filters stack, several entrances of same filter are possible */ + private List prgStack = new ArrayList(); + + /* + * lengths of preceding blocks, one length per filter. Used to reduce size + * required to write block length if lengths are repeating + */ + private List oldFilterLengths = new ArrayList(); + + private int lastFilter; + + private boolean tablesRead; + + private byte[] unpOldTable = new byte[Compress.HUFF_TABLE_SIZE]; + + private BlockTypes unpBlockType; + + private boolean externalWindow; + + private long writtenFileSize; + + private boolean fileExtracted; + + private boolean ppmError; + + private int prevLowDist; + + private int lowDistRepCount; + + public static int[] DBitLengthCounts = { 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 14, 0, 12 }; + + public Unpack(ComprDataIO DataIO) { + unpIO = DataIO; + window = null; + externalWindow = false; + suspended = false; + unpAllBuf = false; + unpSomeRead = false; + } + + public void init(byte[] window) { + // 2012-11-13 RAR解压占用内存问题 修改源代码 + if(this.window == null){ + this.window = new byte[Compress.MAXWINSIZE]; + }else{ + externalWindow = true; + } + /*if (window == null) { + this.window = new byte[Compress.MAXWINSIZE]; + } else { + this.window = window; + externalWindow = true; + }*/ + inAddr = 0; + unpInitData(false); + } + + public void doUnpack(int method, boolean solid) throws IOException, + RarException { + if (unpIO.getSubHeader().getUnpMethod() == 0x30) { + unstoreFile(); + } + switch (method) { + case 15: // rar 1.5 compression + unpack15(solid); + break; + case 20: // rar 2.x compression + case 26: // files larger than 2GB + unpack20(solid); + break; + case 29: // rar 3.x compression + case 36: // alternative hash + unpack29(solid); + break; + } + } + + private void unstoreFile() throws IOException, RarException { + byte[] buffer = new byte[0x10000]; + while (true) { + int code = unpIO.unpRead(buffer, 0, (int) Math.min(buffer.length, + destUnpSize)); + if (code == 0 || code == -1) + break; + code = code < destUnpSize ? code : (int) destUnpSize; + unpIO.unpWrite(buffer, 0, code); + if (destUnpSize >= 0) + destUnpSize -= code; + } + + } + + private void unpack29(boolean solid) throws IOException, RarException { + + int[] DDecode = new int[Compress.DC]; + byte[] DBits = new byte[Compress.DC]; + + int Bits; + + if (DDecode[1] == 0) { + int Dist = 0, BitLength = 0, Slot = 0; + for (int I = 0; I < DBitLengthCounts.length; I++, BitLength++) { + int count = DBitLengthCounts[I]; + for (int J = 0; J < count; J++, Slot++, Dist += (1 << BitLength)) { + DDecode[Slot] = Dist; + DBits[Slot] = (byte) BitLength; + } + } + } + + fileExtracted = true; + + if (!suspended) { + unpInitData(solid); + if (!unpReadBuf()) { + return; + } + if ((!solid || !tablesRead) && !readTables()) { + return; + } + } + + if (ppmError) { + return; + } + + while (true) { + unpPtr &= Compress.MAXWINMASK; + + if (inAddr > readBorder) { + if (!unpReadBuf()) { + break; + } + } + // System.out.println(((wrPtr - unpPtr) & + // Compress.MAXWINMASK)+":"+wrPtr+":"+unpPtr); + if (((wrPtr - unpPtr) & Compress.MAXWINMASK) < 260 + && wrPtr != unpPtr) { + + UnpWriteBuf(); + if (writtenFileSize > destUnpSize) { + return; + } + if (suspended) { + fileExtracted = false; + return; + } + } + if (unpBlockType == BlockTypes.BLOCK_PPM) { + int Ch = ppm.decodeChar(); + if (Ch == -1) { + ppmError = true; + break; + } + if (Ch == ppmEscChar) { + int NextCh = ppm.decodeChar(); + if (NextCh == 0) { + if (!readTables()) { + break; + } + continue; + } + if (NextCh == 2 || NextCh == -1) { + break; + } + if (NextCh == 3) { + if (!readVMCodePPM()) { + break; + } + continue; + } + if (NextCh == 4) { + int Distance = 0, Length = 0; + boolean failed = false; + for (int I = 0; I < 4 && !failed; I++) { + int ch = ppm.decodeChar(); + if (ch == -1) { + failed = true; + } else { + if (I == 3) { + // Bug fixed + Length = ch & 0xff; + } else { + // Bug fixed + Distance = (Distance << 8) + (ch & 0xff); + } + } + } + if (failed) { + break; + } + copyString(Length + 32, Distance + 2); + continue; + } + if (NextCh == 5) { + int Length = ppm.decodeChar(); + if (Length == -1) { + break; + } + copyString(Length + 4, 1); + continue; + } + } + window[unpPtr++] = (byte) Ch; + continue; + } + + int Number = decodeNumber(LD); + if (Number < 256) { + window[unpPtr++] = (byte) Number; + continue; + } + if (Number >= 271) { + int Length = LDecode[Number -= 271] + 3; + if ((Bits = LBits[Number]) > 0) { + Length += getbits() >>> (16 - Bits); + addbits(Bits); + } + + int DistNumber = decodeNumber(DD); + int Distance = DDecode[DistNumber] + 1; + if ((Bits = DBits[DistNumber]) > 0) { + if (DistNumber > 9) { + if (Bits > 4) { + Distance += ((getbits() >>> (20 - Bits)) << 4); + addbits(Bits - 4); + } + if (lowDistRepCount > 0) { + lowDistRepCount--; + Distance += prevLowDist; + } else { + int LowDist = decodeNumber(LDD); + if (LowDist == 16) { + lowDistRepCount = Compress.LOW_DIST_REP_COUNT - 1; + Distance += prevLowDist; + } else { + Distance += LowDist; + prevLowDist = LowDist; + } + } + } else { + Distance += getbits() >>> (16 - Bits); + addbits(Bits); + } + } + + if (Distance >= 0x2000) { + Length++; + if (Distance >= 0x40000L) { + Length++; + } + } + + insertOldDist(Distance); + insertLastMatch(Length, Distance); + + copyString(Length, Distance); + continue; + } + if (Number == 256) { + if (!readEndOfBlock()) { + break; + } + continue; + } + if (Number == 257) { + if (!readVMCode()) { + break; + } + continue; + } + if (Number == 258) { + if (lastLength != 0) { + copyString(lastLength, lastDist); + } + continue; + } + if (Number < 263) { + int DistNum = Number - 259; + int Distance = oldDist[DistNum]; + for (int I = DistNum; I > 0; I--) { + oldDist[I] = oldDist[I - 1]; + } + oldDist[0] = Distance; + + int LengthNumber = decodeNumber(RD); + int Length = LDecode[LengthNumber] + 2; + if ((Bits = LBits[LengthNumber]) > 0) { + Length += getbits() >>> (16 - Bits); + addbits(Bits); + } + insertLastMatch(Length, Distance); + copyString(Length, Distance); + continue; + } + if (Number < 272) { + int Distance = SDDecode[Number -= 263] + 1; + if ((Bits = SDBits[Number]) > 0) { + Distance += getbits() >>> (16 - Bits); + addbits(Bits); + } + insertOldDist(Distance); + insertLastMatch(2, Distance); + copyString(2, Distance); + continue; + } + } + UnpWriteBuf(); + + } + + private void UnpWriteBuf() throws IOException { + int WrittenBorder = wrPtr; + int WriteSize = (unpPtr - WrittenBorder) & Compress.MAXWINMASK; + for (int I = 0; I < prgStack.size(); I++) { + UnpackFilter flt = prgStack.get(I); + if (flt == null) { + continue; + } + if (flt.isNextWindow()) { + flt.setNextWindow(false);// ->NextWindow=false; + continue; + } + int BlockStart = flt.getBlockStart();// ->BlockStart; + int BlockLength = flt.getBlockLength();// ->BlockLength; + if (((BlockStart - WrittenBorder) & Compress.MAXWINMASK) < WriteSize) { + if (WrittenBorder != BlockStart) { + UnpWriteArea(WrittenBorder, BlockStart); + WrittenBorder = BlockStart; + WriteSize = (unpPtr - WrittenBorder) & Compress.MAXWINMASK; + } + if (BlockLength <= WriteSize) { + int BlockEnd = (BlockStart + BlockLength) + & Compress.MAXWINMASK; + if (BlockStart < BlockEnd || BlockEnd == 0) { + // VM.SetMemory(0,Window+BlockStart,BlockLength); + rarVM.setMemory(0, window, BlockStart, BlockLength); + } else { + int FirstPartLength = Compress.MAXWINSIZE - BlockStart; + // VM.SetMemory(0,Window+BlockStart,FirstPartLength); + rarVM.setMemory(0, window, BlockStart, FirstPartLength); + // VM.SetMemory(FirstPartLength,Window,BlockEnd); + rarVM.setMemory(FirstPartLength, window, 0, BlockEnd); + + } + + VMPreparedProgram ParentPrg = filters.get( + flt.getParentFilter()).getPrg(); + VMPreparedProgram Prg = flt.getPrg(); + + if (ParentPrg.getGlobalData().size() > RarVM.VM_FIXEDGLOBALSIZE) { + // copy global data from previous script execution if + // any + // Prg->GlobalData.Alloc(ParentPrg->GlobalData.Size()); + // memcpy(&Prg->GlobalData[VM_FIXEDGLOBALSIZE],&ParentPrg->GlobalData[VM_FIXEDGLOBALSIZE],ParentPrg->GlobalData.Size()-VM_FIXEDGLOBALSIZE); + Prg.getGlobalData().setSize( + ParentPrg.getGlobalData().size()); + for (int i = 0; i < ParentPrg.getGlobalData().size() + - RarVM.VM_FIXEDGLOBALSIZE; i++) { + Prg.getGlobalData().set( + RarVM.VM_FIXEDGLOBALSIZE + i, + ParentPrg.getGlobalData().get( + RarVM.VM_FIXEDGLOBALSIZE + i)); + } + } + + ExecuteCode(Prg); + + if (Prg.getGlobalData().size() > RarVM.VM_FIXEDGLOBALSIZE) { + // save global data for next script execution + if (ParentPrg.getGlobalData().size() < Prg + .getGlobalData().size()) { + ParentPrg.getGlobalData().setSize( + Prg.getGlobalData().size());// ->GlobalData.Alloc(Prg->GlobalData.Size()); + } + // memcpy(&ParentPrg->GlobalData[VM_FIXEDGLOBALSIZE],&Prg->GlobalData[VM_FIXEDGLOBALSIZE],Prg->GlobalData.Size()-VM_FIXEDGLOBALSIZE); + for (int i = 0; i < Prg.getGlobalData().size() + - RarVM.VM_FIXEDGLOBALSIZE; i++) { + ParentPrg.getGlobalData().set( + RarVM.VM_FIXEDGLOBALSIZE + i, + Prg.getGlobalData().get( + RarVM.VM_FIXEDGLOBALSIZE + i)); + } + } else { + ParentPrg.getGlobalData().clear(); + } + + int FilteredDataOffset = Prg.getFilteredDataOffset(); + int FilteredDataSize = Prg.getFilteredDataSize(); + byte[] FilteredData = new byte[FilteredDataSize]; + + for (int i = 0; i < FilteredDataSize; i++) { + FilteredData[i] = rarVM.getMem()[FilteredDataOffset + i];// Prg.getGlobalData().get(FilteredDataOffset + // + + // i); + } + + prgStack.set(I, null); + while (I + 1 < prgStack.size()) { + UnpackFilter NextFilter = prgStack.get(I + 1); + if (NextFilter == null + || NextFilter.getBlockStart() != BlockStart + || NextFilter.getBlockLength() != FilteredDataSize + || NextFilter.isNextWindow()) { + break; + } + // apply several filters to same data block + + rarVM.setMemory(0, FilteredData, 0, FilteredDataSize);// .SetMemory(0,FilteredData,FilteredDataSize); + + VMPreparedProgram pPrg = filters.get( + NextFilter.getParentFilter()).getPrg(); + VMPreparedProgram NextPrg = NextFilter.getPrg(); + + if (pPrg.getGlobalData().size() > RarVM.VM_FIXEDGLOBALSIZE) { + // copy global data from previous script execution + // if any + // NextPrg->GlobalData.Alloc(ParentPrg->GlobalData.Size()); + NextPrg.getGlobalData().setSize( + pPrg.getGlobalData().size()); + // memcpy(&NextPrg->GlobalData[VM_FIXEDGLOBALSIZE],&ParentPrg->GlobalData[VM_FIXEDGLOBALSIZE],ParentPrg->GlobalData.Size()-VM_FIXEDGLOBALSIZE); + for (int i = 0; i < pPrg.getGlobalData().size() + - RarVM.VM_FIXEDGLOBALSIZE; i++) { + NextPrg.getGlobalData().set( + RarVM.VM_FIXEDGLOBALSIZE + i, + pPrg.getGlobalData().get( + RarVM.VM_FIXEDGLOBALSIZE + i)); + } + } + + ExecuteCode(NextPrg); + + if (NextPrg.getGlobalData().size() > RarVM.VM_FIXEDGLOBALSIZE) { + // save global data for next script execution + if (pPrg.getGlobalData().size() < NextPrg + .getGlobalData().size()) { + pPrg.getGlobalData().setSize( + NextPrg.getGlobalData().size()); + } + // memcpy(&ParentPrg->GlobalData[VM_FIXEDGLOBALSIZE],&NextPrg->GlobalData[VM_FIXEDGLOBALSIZE],NextPrg->GlobalData.Size()-VM_FIXEDGLOBALSIZE); + for (int i = 0; i < NextPrg.getGlobalData().size() + - RarVM.VM_FIXEDGLOBALSIZE; i++) { + pPrg.getGlobalData().set( + RarVM.VM_FIXEDGLOBALSIZE + i, + NextPrg.getGlobalData().get( + RarVM.VM_FIXEDGLOBALSIZE + i)); + } + } else { + pPrg.getGlobalData().clear(); + } + FilteredDataOffset = NextPrg.getFilteredDataOffset(); + FilteredDataSize = NextPrg.getFilteredDataSize(); + + FilteredData = new byte[FilteredDataSize]; + for (int i = 0; i < FilteredDataSize; i++) { + FilteredData[i] = NextPrg.getGlobalData().get( + FilteredDataOffset + i); + } + + I++; + prgStack.set(I, null); + } + unpIO.unpWrite(FilteredData, 0, FilteredDataSize); + unpSomeRead = true; + writtenFileSize += FilteredDataSize; + WrittenBorder = BlockEnd; + WriteSize = (unpPtr - WrittenBorder) & Compress.MAXWINMASK; + } else { + for (int J = I; J < prgStack.size(); J++) { + UnpackFilter filt = prgStack.get(J); + if (filt != null && filt.isNextWindow()) { + filt.setNextWindow(false); + } + } + wrPtr = WrittenBorder; + return; + } + } + } + + UnpWriteArea(WrittenBorder, unpPtr); + wrPtr = unpPtr; + + } + + private void UnpWriteArea(int startPtr, int endPtr) throws IOException { + if (endPtr != startPtr) { + unpSomeRead = true; + } + if (endPtr < startPtr) { + UnpWriteData(window, startPtr, -startPtr & Compress.MAXWINMASK); + UnpWriteData(window, 0, endPtr); + unpAllBuf = true; + } else { + UnpWriteData(window, startPtr, endPtr - startPtr); + } + } + + private void UnpWriteData(byte[] data, int offset, int size) + throws IOException { + if (writtenFileSize >= destUnpSize) { + return; + } + int writeSize = size; + long leftToWrite = destUnpSize - writtenFileSize; + if (writeSize > leftToWrite) { + writeSize = (int) leftToWrite; + } + unpIO.unpWrite(data, offset, writeSize); + + writtenFileSize += size; + + } + + private void insertOldDist(int distance) { + oldDist[3] = oldDist[2]; + oldDist[2] = oldDist[1]; + oldDist[1] = oldDist[0]; + oldDist[0] = distance; + } + + private void insertLastMatch(int length, int distance) { + lastDist = distance; + lastLength = length; + } + + private void copyString(int length, int distance) { + // System.out.println("copyString(" + length + ", " + distance + ")"); + + int destPtr = unpPtr - distance; + // System.out.println(unpPtr+":"+distance); + if (destPtr >= 0 && destPtr < Compress.MAXWINSIZE - 260 + && unpPtr < Compress.MAXWINSIZE - 260) { + + window[unpPtr++] = window[destPtr++]; + + while (--length > 0) + + window[unpPtr++] = window[destPtr++]; + } else + while (length-- != 0) { + window[unpPtr] = window[destPtr++ & Compress.MAXWINMASK]; + unpPtr = (unpPtr + 1) & Compress.MAXWINMASK; + } + } + + protected void unpInitData(boolean solid) { + if (!solid) { + tablesRead = false; + Arrays.fill(oldDist, 0); // memset(oldDist,0,sizeof(OldDist)); + + oldDistPtr = 0; + lastDist = 0; + lastLength = 0; + + Arrays.fill(unpOldTable, (byte) 0);// memset(UnpOldTable,0,sizeof(UnpOldTable)); + + unpPtr = 0; + wrPtr = 0; + ppmEscChar = 2; + + initFilters(); + } + InitBitInput(); + ppmError = false; + writtenFileSize = 0; + readTop = 0; + readBorder = 0; + unpInitData20(solid); + } + + private void initFilters() { + oldFilterLengths.clear(); + lastFilter = 0; + + filters.clear(); + + prgStack.clear(); + } + + private boolean readEndOfBlock() throws IOException, RarException { + int BitField = getbits(); + boolean NewTable, NewFile = false; + if ((BitField & 0x8000) != 0) { + NewTable = true; + addbits(1); + } else { + NewFile = true; + NewTable = (BitField & 0x4000) != 0 ? true : false; + addbits(2); + } + tablesRead = !NewTable; + return !(NewFile || NewTable && !readTables()); + } + + private boolean readTables() throws IOException, RarException { + byte[] bitLength = new byte[Compress.BC]; + + byte[] table = new byte[Compress.HUFF_TABLE_SIZE]; + if (inAddr > readTop - 25) { + if (!unpReadBuf()) { + return (false); + } + } + faddbits((8 - inBit) & 7); + long bitField = fgetbits() & 0xffFFffFF; + if ((bitField & 0x8000) != 0) { + unpBlockType = BlockTypes.BLOCK_PPM; + return (ppm.decodeInit(this, ppmEscChar)); + } + unpBlockType = BlockTypes.BLOCK_LZ; + + prevLowDist = 0; + lowDistRepCount = 0; + + if ((bitField & 0x4000) == 0) { + Arrays.fill(unpOldTable, (byte) 0);// memset(UnpOldTable,0,sizeof(UnpOldTable)); + } + faddbits(2); + + for (int i = 0; i < Compress.BC; i++) { + int length = (fgetbits() >>> 12) & 0xFF; + faddbits(4); + if (length == 15) { + int zeroCount = (fgetbits() >>> 12) & 0xFF; + faddbits(4); + if (zeroCount == 0) { + bitLength[i] = 15; + } else { + zeroCount += 2; + while (zeroCount-- > 0 && i < bitLength.length) { + bitLength[i++] = 0; + } + i--; + } + } else { + bitLength[i] = (byte) length; + } + } + + makeDecodeTables(bitLength, 0, BD, Compress.BC); + + int TableSize = Compress.HUFF_TABLE_SIZE; + + for (int i = 0; i < TableSize;) { + if (inAddr > readTop - 5) { + if (!unpReadBuf()) { + return (false); + } + } + int Number = decodeNumber(BD); + if (Number < 16) { + table[i] = (byte) ((Number + unpOldTable[i]) & 0xf); + i++; + } else if (Number < 18) { + int N; + if (Number == 16) { + N = (fgetbits() >>> 13) + 3; + faddbits(3); + } else { + N = (fgetbits() >>> 9) + 11; + faddbits(7); + } + while (N-- > 0 && i < TableSize) { + table[i] = table[i - 1]; + i++; + } + } else { + int N; + if (Number == 18) { + N = (fgetbits() >>> 13) + 3; + faddbits(3); + } else { + N = (fgetbits() >>> 9) + 11; + faddbits(7); + } + while (N-- > 0 && i < TableSize) { + table[i++] = 0; + } + } + } + tablesRead = true; + if (inAddr > readTop) { + return (false); + } + makeDecodeTables(table, 0, LD, Compress.NC); + makeDecodeTables(table, Compress.NC, DD, Compress.DC); + makeDecodeTables(table, Compress.NC + Compress.DC, LDD, Compress.LDC); + makeDecodeTables(table, Compress.NC + Compress.DC + Compress.LDC, RD, + Compress.RC); + + // memcpy(unpOldTable,table,sizeof(unpOldTable)); + for (int i = 0; i < unpOldTable.length; i++) { + unpOldTable[i] = table[i]; + } + return (true); + + } + + private boolean readVMCode() throws IOException, RarException { + int FirstByte = getbits() >> 8; + addbits(8); + int Length = (FirstByte & 7) + 1; + if (Length == 7) { + Length = (getbits() >> 8) + 7; + addbits(8); + } else if (Length == 8) { + Length = getbits(); + addbits(16); + } + List vmCode = new ArrayList(); + for (int I = 0; I < Length; I++) { + if (inAddr >= readTop - 1 && !unpReadBuf() && I < Length - 1) { + return (false); + } + vmCode.add(Byte.valueOf((byte) (getbits() >> 8))); + addbits(8); + } + return (addVMCode(FirstByte, vmCode, Length)); + } + + private boolean readVMCodePPM() throws IOException, RarException { + int FirstByte = ppm.decodeChar(); + if ((int) FirstByte == -1) { + return (false); + } + int Length = (FirstByte & 7) + 1; + if (Length == 7) { + int B1 = ppm.decodeChar(); + if (B1 == -1) { + return (false); + } + Length = B1 + 7; + } else if (Length == 8) { + int B1 = ppm.decodeChar(); + if (B1 == -1) { + return (false); + } + int B2 = ppm.decodeChar(); + if (B2 == -1) { + return (false); + } + Length = B1 * 256 + B2; + } + List vmCode = new ArrayList(); + for (int I = 0; I < Length; I++) { + int Ch = ppm.decodeChar(); + if (Ch == -1) { + return (false); + } + vmCode.add(Byte.valueOf((byte) Ch));// VMCode[I]=Ch; + } + return (addVMCode(FirstByte, vmCode, Length)); + } + + private boolean addVMCode(int firstByte, List vmCode, int length) { + BitInput Inp = new BitInput(); + Inp.InitBitInput(); + // memcpy(Inp.InBuf,Code,Min(BitInput::MAX_SIZE,CodeSize)); + for (int i = 0; i < Math.min(BitInput.MAX_SIZE, vmCode.size()); i++) { + Inp.getInBuf()[i] = vmCode.get(i); + } + rarVM.init(); + + int FiltPos; + if ((firstByte & 0x80) != 0) { + FiltPos = RarVM.ReadData(Inp); + if (FiltPos == 0) { + initFilters(); + } else { + FiltPos--; + } + } else + FiltPos = lastFilter; // use the same filter as last time + + if (FiltPos > filters.size() || FiltPos > oldFilterLengths.size()) { + return (false); + } + lastFilter = FiltPos; + boolean NewFilter = (FiltPos == filters.size()); + + UnpackFilter StackFilter = new UnpackFilter(); // new filter for + // PrgStack + + UnpackFilter Filter; + if (NewFilter) // new filter code, never used before since VM reset + { + // too many different filters, corrupt archive + if (FiltPos > 1024) { + return (false); + } + + // Filters[Filters.Size()-1]=Filter=new UnpackFilter; + Filter = new UnpackFilter(); + filters.add(Filter); + StackFilter.setParentFilter(filters.size() - 1); + oldFilterLengths.add(0); + Filter.setExecCount(0); + } else // filter was used in the past + { + Filter = filters.get(FiltPos); + StackFilter.setParentFilter(FiltPos); + Filter.setExecCount(Filter.getExecCount() + 1);// ->ExecCount++; + } + + prgStack.add(StackFilter); + StackFilter.setExecCount(Filter.getExecCount());// ->ExecCount; + + int BlockStart = RarVM.ReadData(Inp); + if ((firstByte & 0x40) != 0) { + BlockStart += 258; + } + StackFilter.setBlockStart((BlockStart + unpPtr) & Compress.MAXWINMASK); + if ((firstByte & 0x20) != 0) { + StackFilter.setBlockLength(RarVM.ReadData(Inp)); + } else { + StackFilter + .setBlockLength(FiltPos < oldFilterLengths.size() ? oldFilterLengths + .get(FiltPos) + : 0); + } + StackFilter.setNextWindow((wrPtr != unpPtr) + && ((wrPtr - unpPtr) & Compress.MAXWINMASK) <= BlockStart); + + // DebugLog("\nNextWindow: UnpPtr=%08x WrPtr=%08x + // BlockStart=%08x",UnpPtr,WrPtr,BlockStart); + + oldFilterLengths.set(FiltPos, StackFilter.getBlockLength()); + + // memset(StackFilter->Prg.InitR,0,sizeof(StackFilter->Prg.InitR)); + Arrays.fill(StackFilter.getPrg().getInitR(), 0); + StackFilter.getPrg().getInitR()[3] = RarVM.VM_GLOBALMEMADDR;// StackFilter->Prg.InitR[3]=VM_GLOBALMEMADDR; + StackFilter.getPrg().getInitR()[4] = StackFilter.getBlockLength();// StackFilter->Prg.InitR[4]=StackFilter->BlockLength; + StackFilter.getPrg().getInitR()[5] = StackFilter.getExecCount();// StackFilter->Prg.InitR[5]=StackFilter->ExecCount; + + if ((firstByte & 0x10) != 0) // set registers to optional parameters + // if any + { + int InitMask = Inp.fgetbits() >>> 9; + Inp.faddbits(7); + for (int I = 0; I < 7; I++) { + if ((InitMask & (1 << I)) != 0) { + // StackFilter->Prg.InitR[I]=RarVM::ReadData(Inp); + StackFilter.getPrg().getInitR()[I] = RarVM.ReadData(Inp); + } + } + } + + if (NewFilter) { + int VMCodeSize = RarVM.ReadData(Inp); + if (VMCodeSize >= 0x10000 || VMCodeSize == 0) { + return (false); + } + byte[] VMCode = new byte[VMCodeSize]; + for (int I = 0; I < VMCodeSize; I++) { + if (Inp.Overflow(3)) { + return (false); + } + VMCode[I] = (byte) (Inp.fgetbits() >> 8); + Inp.faddbits(8); + } + // VM.Prepare(&VMCode[0],VMCodeSize,&Filter->Prg); + rarVM.prepare(VMCode, VMCodeSize, Filter.getPrg()); + } + StackFilter.getPrg().setAltCmd(Filter.getPrg().getCmd());// StackFilter->Prg.AltCmd=&Filter->Prg.Cmd[0]; + StackFilter.getPrg().setCmdCount(Filter.getPrg().getCmdCount());// StackFilter->Prg.CmdCount=Filter->Prg.CmdCount; + + int StaticDataSize = Filter.getPrg().getStaticData().size(); + if (StaticDataSize > 0 && StaticDataSize < RarVM.VM_GLOBALMEMSIZE) { + // read statically defined data contained in DB commands + // StackFilter->Prg.StaticData.Add(StaticDataSize); + StackFilter.getPrg().setStaticData(Filter.getPrg().getStaticData()); + // memcpy(&StackFilter->Prg.StaticData[0],&Filter->Prg.StaticData[0],StaticDataSize); + } + + if (StackFilter.getPrg().getGlobalData().size() < RarVM.VM_FIXEDGLOBALSIZE) { + // StackFilter->Prg.GlobalData.Reset(); + // StackFilter->Prg.GlobalData.Add(VM_FIXEDGLOBALSIZE); + StackFilter.getPrg().getGlobalData().clear(); + StackFilter.getPrg().getGlobalData().setSize( + RarVM.VM_FIXEDGLOBALSIZE); + } + + // byte *GlobalData=&StackFilter->Prg.GlobalData[0]; + Vector globalData = StackFilter.getPrg().getGlobalData(); + for (int I = 0; I < 7; I++) { + rarVM.setLowEndianValue(globalData, I * 4, StackFilter.getPrg() + .getInitR()[I]); + } + + // VM.SetLowEndianValue((uint + // *)&GlobalData[0x1c],StackFilter->BlockLength); + rarVM.setLowEndianValue(globalData, 0x1c, StackFilter.getBlockLength()); + // VM.SetLowEndianValue((uint *)&GlobalData[0x20],0); + rarVM.setLowEndianValue(globalData, 0x20, 0); + rarVM.setLowEndianValue(globalData, 0x24, 0); + rarVM.setLowEndianValue(globalData, 0x28, 0); + + // VM.SetLowEndianValue((uint + // *)&GlobalData[0x2c],StackFilter->ExecCount); + rarVM.setLowEndianValue(globalData, 0x2c, StackFilter.getExecCount()); + // memset(&GlobalData[0x30],0,16); + for (int i = 0; i < 16; i++) { + globalData.set(0x30 + i, Byte.valueOf((byte) (0))); + } + if ((firstByte & 8) != 0) // put data block passed as parameter if any + { + if (Inp.Overflow(3)) { + return (false); + } + int DataSize = RarVM.ReadData(Inp); + if (DataSize > RarVM.VM_GLOBALMEMSIZE - RarVM.VM_FIXEDGLOBALSIZE) { + return (false); + } + int CurSize = StackFilter.getPrg().getGlobalData().size(); + if (CurSize < DataSize + RarVM.VM_FIXEDGLOBALSIZE) { + // StackFilter->Prg.GlobalData.Add(DataSize+VM_FIXEDGLOBALSIZE-CurSize); + StackFilter.getPrg().getGlobalData().setSize( + DataSize + RarVM.VM_FIXEDGLOBALSIZE - CurSize); + } + int offset = RarVM.VM_FIXEDGLOBALSIZE; + globalData = StackFilter.getPrg().getGlobalData(); + for (int I = 0; I < DataSize; I++) { + if (Inp.Overflow(3)) { + return (false); + } + globalData.set(offset + I, Byte + .valueOf((byte) (Inp.fgetbits() >>> 8))); + Inp.faddbits(8); + } + } + return (true); + } + + private void ExecuteCode(VMPreparedProgram Prg) { + if (Prg.getGlobalData().size() > 0) { + // Prg->InitR[6]=int64to32(WrittenFileSize); + Prg.getInitR()[6] = (int) (writtenFileSize); + // rarVM.SetLowEndianValue((uint + // *)&Prg->GlobalData[0x24],int64to32(WrittenFileSize)); + rarVM.setLowEndianValue(Prg.getGlobalData(), 0x24, + (int) writtenFileSize); + // rarVM.SetLowEndianValue((uint + // *)&Prg->GlobalData[0x28],int64to32(WrittenFileSize>>32)); + rarVM.setLowEndianValue(Prg.getGlobalData(), 0x28, + (int) (writtenFileSize >>> 32)); + rarVM.execute(Prg); + } + } + + // Duplicate method + // private boolean ReadEndOfBlock() throws IOException, RarException + // { + // int BitField = getbits(); + // boolean NewTable, NewFile = false; + // if ((BitField & 0x8000) != 0) { + // NewTable = true; + // addbits(1); + // } else { + // NewFile = true; + // NewTable = (BitField & 0x4000) != 0; + // addbits(2); + // } + // tablesRead = !NewTable; + // return !(NewFile || NewTable && !readTables()); + // } + + public boolean isFileExtracted() { + return fileExtracted; + } + + public void setDestSize(long destSize) { + this.destUnpSize = destSize; + this.fileExtracted = false; + } + + public void setSuspended(boolean suspended) { + this.suspended = suspended; + } + + public int getChar() throws IOException, RarException { + if (inAddr > BitInput.MAX_SIZE - 30) { + unpReadBuf(); + } + return (inBuf[inAddr++] & 0xff); + } + + public int getPpmEscChar() { + return ppmEscChar; + } + + public void setPpmEscChar(int ppmEscChar) { + this.ppmEscChar = ppmEscChar; + } + + public void cleanUp() { + if (ppm != null) { + SubAllocator allocator = ppm.getSubAlloc(); + if (allocator != null) { + allocator.stopSubAllocator(); + } + } + System.out.println(this.window.length); + } +} diff --git a/src/key/bat/create_ks_cert.bat b/src/key/bat/create_ks_cert.bat new file mode 100644 index 0000000..dd3f144 --- /dev/null +++ b/src/key/bat/create_ks_cert.bat @@ -0,0 +1,24 @@ +@echo off +set aliasName=clientkey +set storePath=./client_ks +set local=192.168.10.100 +set keyPass=123123 +set certName=./client_key.cer +if not "%1"=="" ( + set aliasName=%1 +) +if not "%2"=="" ( + set storePath=%2 +) +if not "%3"=="" ( + set local=%3 +) +if not "%4"=="" ( + set keyPass=%4 +) +if not "%5"=="" ( + set certName=%5 +) +@echo %aliasName% %storePath% %local% %keyPass% %certName% +keytool -genkey -v -alias %aliasName% -keyalg RSA -storetype jceks -keystore %storePath% -validity 90 -dname "CN=%local%,OU=cn,O=cn,L=cn,ST=cn,C=cn" -storepass client -keypass %keyPass% +keytool -export -alias %aliasName% -storetype jceks -keystore %storePath% -file %certName% -storepass client diff --git a/src/key/bat/import_trust_cert.bat b/src/key/bat/import_trust_cert.bat new file mode 100644 index 0000000..35c4ee8 --- /dev/null +++ b/src/key/bat/import_trust_cert.bat @@ -0,0 +1,18 @@ +@echo off +@echo Կƣ%1 Կ·ƣ%2 ֤·ƣ%3 +set aliasName=clientkey +set storePath=./client_ks +set local=localhost +set certName=./client_key.cer +if not "%1"=="" ( + set aliasName=%1 +) +if not "%2"=="" ( + set storePath=%2 +) +if not "%3"=="" ( + set certName=%3 +) + +@echo %aliasName% %storePath% %certName% +echo y|keytool -import -v -trustcacerts -alias %aliasName% -keystore %storePath% -file %certName% -storetype jceks -storepass client diff --git a/src/key/cer/client_ks b/src/key/cer/client_ks new file mode 100644 index 0000000..79459cc Binary files /dev/null and b/src/key/cer/client_ks differ diff --git a/src/key/cer/client_ts b/src/key/cer/client_ts new file mode 100644 index 0000000..312ecd6 Binary files /dev/null and b/src/key/cer/client_ts differ diff --git a/src/log4j.properties b/src/log4j.properties new file mode 100644 index 0000000..3bffcbc --- /dev/null +++ b/src/log4j.properties @@ -0,0 +1,26 @@ +log4j.rootLogger = debug,stdout,logfile + +log4j.appender.stdout = org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout.ConversionPattern = %d %p [%l] [%t] - <%m>%n +log4j.appender.stdout.layout = org.apache.log4j.PatternLayout + +#----------------------debug--------------------- + +log4j.appender.logfile = org.apache.log4j.RollingFileAppender +log4j.appender.logfile.MaxFileSize = 50MB +log4j.appender.logfile.MaxBackupIndex = 20 + +log4j.appender.logfile.File = ../nc_logs/nmsclient.log +log4j.appender.logfile.layout.ConversionPattern = %d %p [%l] [%t] - <%m>%n +log4j.appender.logfile.layout = org.apache.log4j.PatternLayout + +#----------------------error--------------------- +log4j.logger.errorLog = warn,errorLog +log4j.appender.errorLog = org.apache.log4j.RollingFileAppender +log4j.appender.errorLog.MaxFileSize = 50MB +log4j.appender.errorLog.Append = true +log4j.appender.errorLog.Threshold = warn +log4j.appender.errorLog.MaxBackupIndex = 10 +log4j.appender.errorLog.File = ../nc_logs/error.log +log4j.appender.errorLog.layout.ConversionPattern = %d %p [%l] [%t] - <%m>%n +log4j.appender.errorLog.layout = org.apache.log4j.PatternLayout diff --git a/src/myconfig.properties b/src/myconfig.properties new file mode 100644 index 0000000..856938b --- /dev/null +++ b/src/myconfig.properties @@ -0,0 +1,87 @@ +#-------------------需要修改配置(Local Path)----------------- +# 文件存放总路径,不要放于NmsClient部署目录下,根据盘符相应修改 +local.data.path = D:/nms/nmsdata +# 可删范围,只有在此路径下的文件Agent才可以删除,多个路径逗号隔开 +common.del.path.include=D:/nms/nmsclient,D:/nms/nmsdata +# 禁删范围,Agent可删路径下不能删除的路径,多个路径逗号隔开(注:若是禁删配置有单个文件,需相应修改代码) +common.del.path.exclude=D:/nms/nmsclient/bin,D:/nms/nmsclient/lib,D:/nms/nmsclient/shell,D:/nms/nmsclient/conf +#------------------------SSLSocket---------------------- +# DataController部署的主机IP,需对应修改 +server_host = 10.0.6.100 +# DataController端的监听端口,用来与Server通信 +server_port = 60702 +# NMSClient自己的监听端口,用来接收Server发送的信息 +agent_port = 60701 +# SSL通信,此值不能更改 +local.ssl.keys=./bin/cer/client_ks +local.ssl.trust=./bin/cer/client_ts +local.ssl.path=./bin/cer +# socket通信超时时间 +socket.timeout.minutes=30 +#------------------------Common------------------------ +# 写文件与通信流默认编码 +charset =UTF-8 +# 删除日志文件,单位天,默认保存七天,可根据情况修改 +common.del.log.days=7 +# 删除数据文件(包括监测数据和任务相关文件),单位小时,默认保存24小时,可根据情况修改 +common.del.data.hours=24 +# 删除升级时推送过来的文件,单位天,默认保存90天,可根据情况修改 +common.del.upgradefile.days=90 +# 删除临时文件,单位天,默认保存2天,可根据情况修改 +common.del.temp.days=2 +# 上传数据循环间隔,默认5分钟上传一次,可根据情况修改【数据由Server主动收集,该属性 废弃】 +common.upload.data.minutes=5 +# 定时清理内存中已完成的任务时间间隔,单位小时,默认2小时 +common.task.clear.hours=2 +#------------------------ThreadPool------------------------ +# Socket通讯线程池最大个数 +common.thread.socket.size=10 +# 定时执行线程池最大个数 +common.thread.schedule.size=15 +#------------------------Compress-------------------------- +# 文件累积达到一定数量压缩打包上传,默认1000个,可修改 +common.zip.min.size=1000 +# 压缩打包最多包含文件个数,默认2000个,可修改 +common.zip.max.size=2000 +# 回传文件累积达到一定数量压缩打包上传,默认10个,可修改 +common.max.return.size=10 +#-------------------------Local Path------------------------- +# 自己写的脚本存放路径,不需修改 +local.script.path = ./shell +# 监测配置基本信息文件后缀 +local.config.file.suffix = .cfg +# NmsClient启动后PID存放文件,需与启动脚本中一致,建议不修改 +local.agent.pidfile = ./temp/agentPid.temp +#-----------------系统预定义的监测类型(不需修改)---------------- +sys.check.type.cpu=cpu +sys.check.type.disk=disk +sys.check.type.memory=memory +sys.check.type.net=net +sys.check.type.systemdate=systemdate +sys.check.type.process=process +sys.check.type.process.nmsagent=nmsclient +sys.check.type.systeminfo=systeminfo +#------------------Debug调试使用(不需修改)--------------------- +debug.init.task.flag = 0 +debug.plugin.flag = 0 +debug.sysdetect.flag = 0 +#--【数据由Server主动收集,该属性 废弃】 +debug.uploaddata.flag = 0 +debug.alarm.flag = 0 +debug.delfile.flag = 0 +#--【数据由Server主动收集,该属性 废弃】 +debug.taskresult.flag = 0 +#--【数据由Server主动收集,该属性 废弃】 +debug.taskreturn.flag =0 +active.alarm.start=true +#监测数据设置告警时,对于指定多个标识符(如多个盘符、多个CPU、多个网卡)的分隔符 +alarm.set.marker.separator=| + +#监测数据主动上报,0:启用,1:不启用 +data.send.thread.flag=0 +#主动数据上报 ip,不填默认为 server_host 的值 +data.send.thread.host= +#主动数据上报 port,默认:9527 +data.send.thread.port=9527 +#主动数据上报间隔 interval,单位 s,默认为 10s +data.send.thread.interval=10 \ No newline at end of file diff --git a/src/old/thread/UpgradeOper.java b/src/old/thread/UpgradeOper.java new file mode 100644 index 0000000..193287e --- /dev/null +++ b/src/old/thread/UpgradeOper.java @@ -0,0 +1,71 @@ +package old.thread; + +import org.apache.log4j.Logger; + +public class UpgradeOper { + static Logger logger = Logger.getLogger(UpgradeOper.class); + + public static boolean checkAgentVersionAndUpdate(){ + boolean flag = true; + /*String curVer = VersionCfg.getValue(); + SSLClient sc = null; + try { + logger.info("检查最新版本……"); + + sc = new SSLClient(); + sc.sendMessageByChar("char:agentVersion"); + String str = sc.receiveMessageByChar();//system type + sc.sendMessageByChar(System.getProperty("os.name")); + str = sc.receiveMessageByChar();//version num + + long newVersion = Long.parseLong(str); + if (newVersion > Long.parseLong(curVer)) { + logger.info("正在下载最新版本" + str); + sc.sendMessageByChar("download"); + str = sc.receiveMessageByChar();// 文件相关属性 + sc.sendMessageByChar(CommonSocket.SUCCESS); + JSONObject jsonObj = JSONObject.fromObject(str); + + Object obj = JSONObject.toBean(jsonObj, Task6.class); + Task6 task = (Task6) obj; + // 接收升级文件 + String error = new TaskReqHandle().filePush(sc, task.getCommandParam(), + task.getTaskId(), true); + flag = (error!=null && error.length()>0) ? true : false; + if (flag) { + sc.sendMessageByChar(AgentCommand.RESULT_SEND_OK + + TaskResultOper.TASK_RESULT_MSG_SEPRATOR + "下发成功"); + CommandPO command = new CommandPO(); + command.setExecId(task.getTaskId()); + command.setExecType(task.getTaskType()); + command.setCommandName(task.getCommandName()); + command.setCommandParam(task.getCommandParam()); + command.setExecState(task.getState()); + command.setExecVersion(task.getVersion()); + command.setSrcPath(TaskReqHandle.getUpgradeTaskPushPath(task.getTaskId())); + flag = new AgentCommand(command).execAndSendResult( + AgentCommand.UpgradeSteps.upgrade_agent.toString(), + task.getCommandParam());// 相应的升级操作及各步骤结果状态的发送 + } else { + sc.sendMessageByChar(AgentCommand.RESULT_FAIL + + TaskResultOper.TASK_RESULT_MSG_SEPRATOR + + "下发失败,详细信息如下: " + error); + } + sc.receiveMessageByChar(); + } else { + sc.sendMessageByChar(CommonSocket.SUCCESS); + logger.info("当前”" + curVer + "“是最新版本, 不用更新"); + } + } catch (Exception e) { + logger.error("检查更新最新版本失败" ); + logger.error(Utils.printExceptionStack(e)); + flag = false; + } finally { + if (sc != null) + sc.close(); + }*/ + + return flag; + } + +} diff --git a/src/test/HotSwapCL.java b/src/test/HotSwapCL.java new file mode 100644 index 0000000..488e27a --- /dev/null +++ b/src/test/HotSwapCL.java @@ -0,0 +1,73 @@ +package test; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashSet; +import org.apache.log4j.Logger; + +import com.nis.nmsclient.util.Utils; + +class HotSwapCL extends ClassLoader { + private Logger logger = Logger.getLogger(ClassLoader.class); + private String basedir; // 需要该类加载器直接加载的类文件的基目录 + private HashSet dynaclazns; // 需要由该类加载器直接加载的类名 + + public HotSwapCL(String basedir, String[] clazns) { + super(null); // 指定父类加载器为 null + this.basedir = basedir; + dynaclazns = new HashSet(); + loadClassByMe(clazns); + } + + private void loadClassByMe(String[] clazns) { + for (int i = 0; i < clazns.length; i++) { + try { + loadDirectly(clazns[i]); + } catch (Exception e) { + logger.error(Utils.printExceptionStack(e)); + } + dynaclazns.add(clazns[i]); + } + } + + private Class loadDirectly(String name) throws Exception{ + Class cls = null; + StringBuffer sb = new StringBuffer(basedir); + String classname = name.replace('.', File.separatorChar) + ".class"; + sb.append(File.separator + classname); + + File classF = new File(sb.toString()); + cls = instantiateClass(name, new FileInputStream(classF), classF + .length()); + return cls; + } + + private Class instantiateClass(String name, InputStream fin, long len) throws Exception{ + byte[] raw = new byte[(int) len]; + try { + fin.read(raw); + } catch (IOException e) { + throw e; + }finally{ + if(fin!=null){ + fin.close(); + } + } + return defineClass(name, raw, 0, raw.length); + } + + protected Class loadClass(String name, boolean resolve) + throws ClassNotFoundException { + Class cls = null; + cls = findLoadedClass(name); + if (!this.dynaclazns.contains(name) && cls == null) + cls = getSystemClassLoader().loadClass(name); + if (cls == null) + throw new ClassNotFoundException(name); + if (resolve) + resolveClass(cls); + return cls; + } +} diff --git a/src/test/Test.java b/src/test/Test.java new file mode 100644 index 0000000..9100a94 --- /dev/null +++ b/src/test/Test.java @@ -0,0 +1,182 @@ +package test; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; + +import com.nis.nmsclient.common.Contants; +import com.nis.nmsclient.util.DateUtil; +import com.nis.nmsclient.util.FileUtil; +import com.nis.nmsclient.util.FileWrUtil; + +public class Test { + public static void main(String[] args) { + //method2(); + //method1(); + + /*File file = new File("C:\\Documents and Settings\\zhenzhen\\桌面\\nmsdata\\test1"); + long now = System.currentTimeMillis(); + + File[] files = file.listFiles(); + for(File file2 : files){ + System.out.println("========"+file2.getName()); + } + System.out.println(System.currentTimeMillis()-now); + + now = System.currentTimeMillis(); + + String[] fileNames = file.list(); + for(String file2 : fileNames){ + System.out.println("========"+file2); + } + System.out.println(System.currentTimeMillis()-now);*/ + /*try { + long now = System.currentTimeMillis(); + ProcessUtil.getProcessId("javaw.exe"); + System.out.println(System.currentTimeMillis()-now); + } catch (Exception e) { + e.printStackTrace(); + }*/ + + /*try { + FileUtils.copyDirectoryToDirectory(new File("D:\\temp\\test"), new File("D:\\temp\\t1")); + FileUtils.copyDirectory(new File("D:\\temp\\test"), new File("D:\\temp\\test2")); + File file = new File("D:\\temp\\tt\\temp"); + if(file.getParentFile().canWrite()){ + System.out.println("Yes"); + } + String[] except = new String[3]; + except[0]="D:\\temp\\test\\WebRoot"; + except[1]="D:\\temp\\test\\t1.tar.gz"; + except[2]="D:\\temp\\test\\src\\filemgr\\ZipUtil.java"; + //new AgentCommand().backup(new File("D:\\temp\\test"), new File("D:\\temp\\t2"), except); + } catch (Exception e) { + e.printStackTrace(); + }*/ + /*String filepath = ""; + if(filepath.startsWith("/") || (filepath.length()>3 && filepath.substring(1,3).equals(":\\"))){ + System.out.println("ff"); + }*/ + /*File file = new File("D:\\temp"); + File file2 = new File("D:\\temp\\test\\.."); + System.out.println(file.compareTo(file2)); + try{ + System.out.println(file.getCanonicalPath() + "--" + file2.getCanonicalPath()); + }catch (Exception e) { + // TODO: handle exception + }*/ + try { + //ProcessUtil.runExec("D:/test.bat"); + /*ProcessUtil.runExec("D:\\Program Files\\PLSQL Developer\\plsqldev.exe"); + String cmd ="D:/Program Files/Navicat for MySQL/navicat.exe"; + Runtime.getRuntime().exec("cmd /c " + cmd.replace(" ", "\" \"")); + //ProcessUtil.runExec("D:/Program Files/feiq/飞秋FeiQ.exe"); + String tempString = "0"; + int length = tempString.split(":").length; + System.out.println(length);*/ + + /*Properties prop = System.getProperties(); + for(Map.Entry entry : prop.entrySet()){ + System.out.println(entry.getKey()+"="+entry.getValue()); + }*/ + + System.out.println(Contants.class.getClassLoader().getResource("myconfig.properties").getPath()) ; + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + + public static void method1(){ + long curDate = System.currentTimeMillis(); + + // 删除指定分钟之前的所有监测文件 + File file = new File("C:/Documents and Settings/zhenzhen/桌面/nmsdata/test"); + if (!file.exists()) { + return; + } + File[] dirs = FileUtil.getDirectoryArray(file); + if (dirs == null || dirs.length <= 0) { + return; + } + for (File dir : dirs) { + File[] files = FileUtil.getFilesEndWith(dir, ".csv"); + if (files == null || files.length <= 0) { + return; + } + for (File f : files) { + long diff = DateUtil.getMinutesFromBeginToEnd(f.lastModified(), curDate); + + if (f.exists() && diff > 1) { + f.delete(); + } + } + } + + System.out.println("=========method1 : " + (System.currentTimeMillis()-curDate)); + } + + public static void method2(){ + try { + long curDate = System.currentTimeMillis(); + + List arrayList = new ArrayList(); + + // 删除指定分钟之前的所有监测文件 + File file = new File("D:/test1"); + if (!file.exists()) { + return; + } + File[] dirs = FileUtil.getDirectoryArray(file); + if (dirs == null || dirs.length <= 0) { + return; + } + for (File dir : dirs) { + File[] files = FileUtil.getFilesEndWith(dir, ".csv"); + if (files == null || files.length <= 0) { + return; + } + for (File f : files) { + //arrayList.add(f.getAbsolutePath()); + FileWrUtil.cfgFileAppender(new File("C:/Documents and Settings/zhenzhen/桌面/nmsdata/test.txt"), "utf-8", new String[]{f.getAbsolutePath()}); + } + } + + //String[] tmp = new String[arrayList.size()]; + //FileWrUtil.cfgFileAppender(new File("C:/Documents and Settings/zhenzhen/桌面/nmsdata/test.txt"), "utf-8", arrayList.toArray(tmp)); + + System.out.println("=========method2 Write end : " + (System.currentTimeMillis()-curDate)); + + curDate = System.currentTimeMillis(); + + FileInputStream in = new FileInputStream(new File("C:/Documents and Settings/zhenzhen/桌面/nmsdata/test.txt")); + BufferedReader bReader = new BufferedReader(new InputStreamReader(in, Contants.charset)); + String line = ""; + List arrList = new ArrayList(); + while ((line = bReader.readLine()) != null){ + /*File file2 = new File(line); + if(file2.exists()){ + file2.delete(); + }*/ + arrList.add(new File(line)); + } + bReader.close(); + in.close(); + System.out.println("=========method2 : " + (System.currentTimeMillis()-curDate)); + curDate = System.currentTimeMillis(); + for(File file3 : arrList){ + if(file3.exists()){ + file3.delete(); + } + } + + System.out.println("=========method2 : " + (System.currentTimeMillis()-curDate)); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/src/test/Test1.java b/src/test/Test1.java new file mode 100644 index 0000000..9b38f03 --- /dev/null +++ b/src/test/Test1.java @@ -0,0 +1,342 @@ +package test; + +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import com.nis.nmsclient.common.Common; + + +public class Test1 { + + private Thread singleThread; + public void testThread(){ + int i = 0; + final long loopDelay = 1l; + final long delay = 0; + ScheduledFuture taskFuture = null; + final String threadName = "测试线程"; + taskFuture = Common.scheduled.schedule(new Runnable() { + public void run() { + synchronized (singleThread) { + singleThread = Thread.currentThread(); + } + Thread.currentThread().setName(threadName + " 周期单次"); + System.out.println("new AgentCommand(command).exec();"); + } + }, 0, TimeUnit.MILLISECONDS); + ThreadNN tt = new ThreadNN(taskFuture, threadName, singleThread); + taskFuture = Common.scheduled.scheduleAtFixedRate( + tt, delay, 6 * 1000, TimeUnit.MILLISECONDS); + try { + Thread.sleep(10*1000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + //if(i>1){ + tt.cancle(); + System.out.println(i+";taskFuture.isCancelled():"+taskFuture.isCancelled()); + System.out.println(i+";taskFuture.isDone():"+taskFuture.isDone()); + System.out.println(i+";taskFuture.cancel(true):"+taskFuture.cancel(true)); + System.out.println(i+";taskFuture.cancel(true):"+taskFuture.cancel(false)); + System.out.println(i+";taskFuture.isCancelled():"+taskFuture.isCancelled()); + System.out.println(i+";taskFuture.isDone():"+taskFuture.isDone()); + //System.out.println(i+";runnable.stop()before;runnable.getState():"+runnable.getState()); + //runnable.notify(); + + //runnable.destroy(); + //runnable.stop(); + + //System.out.println(i+";runnable.stop();runnable.getState():"+runnable.getState()); + //System.out.println(i+";runnable.stop();runnable.getState():"+runnable.getState()); + //System.out.println(i+";runnable.stop();taskFuture.isCancelled():"+taskFuture.isCancelled()); + System.out.println(i+";runnable.stop();taskFuture.isDone():"+taskFuture.isDone()); + //taskFuture = null; + //StringUtils.isNotEmpty(new StringBuilder()); + + //} + } + public static void main(String args[]){ + Test1 t = new Test1(); + t.testThread(); + } + + static class ThreadNN extends Thread{ + private ScheduledFuture singleFuture; + private String threadName; + private ScheduledFuture lastFuture = null; + private long i = 0; + private Thread thread; + private Thread singleThread; + + public ThreadNN(ScheduledFuture singleFuture, String threadName, Thread singleThread){ + this.singleFuture = singleFuture; + this.threadName = threadName; + this.singleThread = singleThread; + } + + public synchronized void cancle() { + if(thread!=null && thread.isAlive()){ + System.out.println("------thread.isAlive()------" + thread.isAlive()); + thread.stop(); + System.out.println("------thread.isAlive()------" + thread.isAlive()); + } + } + + public void run() { + i++; + Thread.currentThread().setName(threadName + " 周期" + i); + System.out.println(i+"--start====="+this.getState()); + long et = System.currentTimeMillis();// 本次开始时间,即上次执行结束时间 + long st = et;// - (i * loopDelay * 60 * 1000);// 上次开始时间 + try { + if (i == 1 && singleFuture != null + && !singleFuture.isCancelled() + && !singleFuture.isDone()) { + synchronized (singleThread) { + if(singleThread!=null){ + singleThread.stop(); + System.out.println("singleThread Timeout stop thread--" + thread.isAlive()); + singleThread = null; + } + } + singleFuture.cancel(true); + } + if (lastFuture != null + && !lastFuture.isCancelled() + && !lastFuture.isDone() && thread!=null) { + thread.stop(); + System.out.println(i+"--LoopTaskThread run Timeout stop thread--" + thread.isAlive()); + lastFuture.cancel(true); + lastFuture = null; + thread = null; + System.out.println(i+"--TaskResultOper.sendTaskResult(command.getExecId(),command.getExecType(),AgentCommand.RESULT_FAIL,本周期任务执行超时, , new Date(st),new Date(et), command.getIsLoop());"); + } + lastFuture = Common.scheduled.schedule(new Runnable() { + public void run() { + thread = Thread.currentThread(); + Thread.currentThread().setName(threadName + " 周期" + i); + System.out.println(i+"---新周期的执行new AgentCommand(command).exec()"); + + for(long j=0l;j<=2000000000; j++){ + if(j==0 || j==100 || j==1000 || j==10000 || j==100000 || j==1000000 || j==2000000000){ + System.out.println(i+"--------"+j); + } + } + } + }, 0, TimeUnit.MILLISECONDS); + System.out.println(i+"--end====="+this.getState()); + //lastFuture.get(); + System.out.println(i+"--last====="+this.getState()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + } + /** + * 回传文件:先将信息写入临时文件,再判断与Server端通信是否成功 + * 1、通信成功:回传所有文件,发送最终结果;删除临时文件 + * 2、通信失败:保留临时文件,直接返回 + * @param rfPo 回传文件实体类 + */ +// public void sendTaskReturnFile(ReturnFilePO rfPo) { +// if(rfPo==null || rfPo.getFilePathMap()==null || rfPo.getFilePathMap().size()<=0){ +// logger.warn("无回传文件, 不用回传"); +// return; +// } +// File tempDir = null; +// try { +// /** +// * 步骤1、将信息写入文件 +// */ +// final File file = new File(getTaskReturnFile(rfPo.getTaskType(), +// rfPo.getTaskId())); +// if (!file.exists()) { +// String[] values = new String[] { JSONObject.fromObject( +// rfPo).toString() }; +// FileWrUtil.cfgFilePrinter(file, Contants.charset, +// values); +// } +// /** +// * 步骤2、与Server通信 +// */ +// Future serFuture = ThreadPool.service.submit(new SSLClient( +// Thread.currentThread().getName(), +// CommonSocket.REQ_HAND_SHAKE, null)); +// if (!SSLClient.isSucessByResult((String) serFuture.get())) { +// return; +// } +// /** +// * 步骤3、回传文件 +// */ +// StringBuffer sb = new StringBuffer(); +// if(rfPo.getResDesc()!=null){//取已有的结果描述信息 +// sb.append(rfPo.getResDesc()); +// } +// if(rfPo.getFilePathMap()!=null && rfPo.getFilePathMap().size()>0){ +// tempDir = new File(Contants.localTempPath + File.separator +// + "return_" + rfPo.getTaskId()); +// if(!tempDir.exists()){ +// tempDir.mkdirs(); +// } +// /** +// * 步骤3-1 处理回传文件:1、过滤不存在或文件路径为空的文件 2、处理文件别名并对文件夹压缩,或对文件重命名 +// */ +// Set> entrySet = rfPo.getFilePathMap().entrySet(); +// for(Map.Entry entry : entrySet){ +// String returnPath = entry.getKey(); +// String aliasName = entry.getValue(); +// if (StringUtils.isEmpty(returnPath)) { +// sb.append("回传“" + returnPath + "”失败,回传文件路径值为空;"); +// rfPo.getFilePathMap().remove(returnPath); +// continue; +// } +// File returnFile = new File(returnPath); +// if (!returnFile.exists()) { +// sb.append("回传“" + returnPath + "”失败,回传文件不存在;"); +// rfPo.getFilePathMap().remove(returnPath); +// continue; +// } +// //回传文件取别名,用于Server端断点续传 +// if(aliasName==null || aliasName.length()<=0){ +// aliasName = CommonSocket.addTimeTagForFileName( +// returnFile.getName(), rfPo.getTaskId()); +// if(returnFile.isDirectory()){ +// aliasName += CompressFileMgr.getCompressSuffixByOs(false); +// } +// rfPo.getFilePathMap().put(returnPath, aliasName); +// } +// // 文件夹的话压缩,文件直接回传 +// File returnTmpFile = new File(tempDir.getCanonicalPath() +// + File.separator +// + aliasName); +// if(!returnTmpFile.exists()){ +// if (returnFile.isDirectory()) { +// new CompressFileMgr().compressFile(returnFile +// .getAbsolutePath(), returnTmpFile +// .getAbsolutePath(), null, false); +// } else { +// FileUtils.copyFile(returnFile, returnTmpFile); +// } +// } +// } +// +// /** +// * 步骤3-2 将处理后的回传文件信息重新写入文件 +// */ +// rfPo.setResDesc(sb.toString()); +// String[] values = new String[] { JSONObject.fromObject( +// rfPo).toString() }; +// FileWrUtil.cfgFilePrinter(file, Contants.charset, +// values); +// +// /** +// * 步骤3-3 开始回传文件 +// */ +// entrySet = rfPo.getFilePathMap().entrySet(); +// List successKeys = new ArrayList(); +// for(Map.Entry entry : entrySet){ +// String key = entry.getKey(); +// File returnFile = new File(tempDir.getCanonicalPath() +// + File.separator +// + entry.getValue()); +// rfPo.setCurRetrunFile(returnFile); +// +// for(int i=0; i future = ThreadPool.service.submit(new SSLClient( +// Thread.currentThread().getName(), +// CommonSocket.REQ_TASK_RETURNFILE, rfPo)); +// String msg = (String) future.get(); +// if(SSLClient.isSucessByResult(msg)){ +// sb.append("回传“" + key + "”成功;"); +// successKeys.add(key); +// break; +// } +// +// try {// 如果更新失败,让当前线程暂停几秒,再重试 +// Thread.sleep(1000 * Contants.max_delay_seconds); +// } catch (InterruptedException e) { +// logger.error(Utils.printExceptionStack(e)); +// continue; +// } +// } +// //sb.append("回传“" + returnPath + "”" + (resultDesc==null ? "失败" : resultDesc) + ";"); +// }// for end +// for(String key : successKeys){ +// rfPo.getFilePathMap().remove(key); +// } +// } +// +// /** +// * 步骤4、判断文件是否全部回传完成 +// */ +// if(rfPo.getFilePathMap().size()==0){ +// /** +// * 步骤4-1、发送任务结果 +// */ +// TaskResultOper.sendTaskResult(rfPo.getTaskId(), rfPo.getTaskType(), +// rfPo.getState(), sb.toString(), "", rfPo.getStartTime(), +// rfPo.getEndTime(), rfPo.getIsLoop()); +// /** +// * 步骤4-2、删除保存回传文件信息的文件 +// */ +// if(file.exists()){ +// file.delete(); +// } +// /** +// * 步骤4-3、正常回传完成,删除临时文件 +// */ +// if(tempDir!=null && tempDir.exists()){ +// try { +// FileUtils.deleteDirectory(tempDir); +// } catch (IOException e) { +// } +// } +// }else{ +// /** +// * 步骤4-1 将下次需要回传的文件重新写入文件 +// */ +// rfPo.setResDesc(sb.toString()); +// String[] values = new String[] { JSONObject.fromObject( +// rfPo).toString() }; +// FileWrUtil.cfgFilePrinter(file, Contants.charset, +// values); +// } +// } catch (Exception e) { +// logger.error(Utils.printExceptionStack(e)); +// }finally{ +// if(tempDir!=null && tempDir.exists() && tempDir.listFiles().length==0){ +// try { +// FileUtils.deleteDirectory(tempDir); +// } catch (IOException e) { +// } +// } +// } +// return; +// } + + + //----------打包上传数据中的部分代码 + //移动文件到临时文件 + /*File destDir = new File(Contants.localDataCollection + File.separator + "temp_data"); + for(File dir : dataDirs){ + File[] files = FileUtil.getFilesEndWith(dir, ".csv"); + if (files == null || files.length <= 0) { + continue; + } + for(File file : files){ + FileUtil.moveFile(file, destDir.getAbsolutePath(), dir.getName(), true); + } + } + //压缩文件 + String compressFileStr = Contants.localDataCollection + + File.separator + + CommonSocket.addTimeTagForFileName("detectdata", + null) + + CompressFileMgr.getCompressSuffixByOs(false); + new CompressFileMgr().compressFile(destDir + .getAbsolutePath(), compressFileStr, null, false); + //删除临时文件 + FileUtils.deleteDirectory(destDir);*/ +} diff --git a/src/test/TestNet.java b/src/test/TestNet.java new file mode 100644 index 0000000..e33da29 --- /dev/null +++ b/src/test/TestNet.java @@ -0,0 +1,151 @@ +package test; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.util.Scanner; + +import org.hyperic.sigar.FileSystem; +import org.hyperic.sigar.FileSystemUsage; +import org.hyperic.sigar.NetFlags; +import org.hyperic.sigar.NetInterfaceConfig; +import org.hyperic.sigar.NetInterfaceStat; +import org.hyperic.sigar.Sigar; +import org.hyperic.sigar.SigarException; + + +public class TestNet { + + /** + * @param args + */ + public static void main(String[] args) { + try { + Sigar sigar = new Sigar(); + + FileSystem fslist[] = sigar.getFileSystemList(); + for (int i = 0; i < fslist.length; i++) { + FileSystem fs = fslist[i]; + try { + FileSystemUsage usage = sigar.getFileSystemUsage(fs.getDirName()); + if (fs.getType() == 2) {// 先取每个盘符的大小和剩余空间 + OutputStreamWriter fos = null; + File file = new File(fs.getDirName() + File.separator + "writetest.temp"); + System.out.println("-----------file path--" + file.getAbsolutePath()); + try { + String testStr = "测试硬盘是否可写,现在开始写入文件"; + fos = new OutputStreamWriter( + new FileOutputStream(file), "utf-8"); + fos.write(testStr); + fos.flush(); + } catch (IOException e) { + System.out.println("测试硬盘是否可写:" + e.getMessage()); + }finally { + if(fos!=null){ + try { + fos.close(); + } catch (IOException e) { + } + } + } + if(file.exists()){ + file.delete(); + System.out.println("---------file delete=" + file.getAbsolutePath()); + } + } + } catch (SigarException e) { + if (fs.getType() == 2) + throw e; + continue; + } + } + + String ifNames[] = sigar.getNetInterfaceList(); + if(ifNames.length >0){ + System.out.println("========= all list =========="); + for (int i = 0; i < ifNames.length; i++) { + String name = ifNames[i]; + try { + NetInterfaceConfig ifconfig = sigar.getNetInterfaceConfig(name); + System.out + .println(name + + "\t" + + ifconfig.getType() + + "\t" + + ifconfig.getFlags() + + "---((ifconfig.getFlags()&NetFlags.IFF_POINTOPOINT)>0)=" + + ((ifconfig.getFlags() & NetFlags.IFF_POINTOPOINT) > 0) + + "---((ifconfig.getFlags()&NetFlags.IFF_LOOPBACK)>0)=" + + ((ifconfig.getFlags() & NetFlags.IFF_LOOPBACK) > 0) + + "---((ifconfig.getFlags()&NetFlags.IFF_BROADCAST)<=0)=" + + ((ifconfig.getFlags() & NetFlags.IFF_BROADCAST) <= 0) + + "---((ifconfig.getFlags()&NetFlags.IFF_MULTICAST)<=0)=" + + ((ifconfig.getFlags() & NetFlags.IFF_MULTICAST) <= 0) + + "\t---((ifconfig.getFlags()&NetFlags.IFF_UP)<=0)=" + + ((ifconfig.getFlags() & NetFlags.IFF_UP) <= 0)); + } catch (SigarException e) { + System.out.println(name); + continue; + } + } + + System.out.println("========= net list =========="); + for (int i = 0; i < ifNames.length; i++) { + String name = ifNames[i]; + try { + NetInterfaceConfig ifconfig = sigar.getNetInterfaceConfig(name); + // *** 网卡类型:ethernet, Local Loopback(本地环回网卡) + /*if (!"ethernet".equalsIgnoreCase(ifconfig.getType())) { + continue; + }*/ + // *** 这里只取 ethernet 网卡类型 + + if ((ifconfig.getFlags() & NetFlags.IFF_POINTOPOINT) > 0) { + continue; + } + if ((ifconfig.getFlags() & NetFlags.IFF_LOOPBACK) > 0) { + continue; + } + if ((ifconfig.getFlags() & NetFlags.IFF_BROADCAST) <= 0) {// broadcast地址无效 + continue; + } + if ((ifconfig.getFlags() & NetFlags.IFF_MULTICAST) <= 0) {// 不支持multicast + continue; + } + if ((ifconfig.getFlags() & NetFlags.IFF_UP) <= 0) { + continue; + } + System.out.println(name + "--" + ifconfig.getAddress()); + } catch (SigarException e) { + continue; + } + } + + Scanner sc = new Scanner(System.in); + while(true){ + System.out.print("\nplease enter net name:"); + String name = sc.nextLine(); + if("quit".equalsIgnoreCase(name)){ + break; + } + if(name==null || "".equals(name)){ + continue; + } + System.out.println("-----------" + name + "------------"); + try{ + NetInterfaceStat ifstat = sigar.getNetInterfaceStat(name); + System.out.println("speed: " + ifstat.getSpeed() + "b/s\nRxPackets: " + ifstat.getRxPackets() + "\nTxPackets: " + ifstat.getTxPackets()); + } catch (SigarException e) { + e.printStackTrace(); + } + } + } + + } catch (SigarException e) { + System.err.println("获取网络信息异常"); + e.printStackTrace(); + } + } + +} diff --git a/src/version.properties b/src/version.properties new file mode 100644 index 0000000..058feef --- /dev/null +++ b/src/version.properties @@ -0,0 +1,2 @@ +NA_version = 1 +NS_version = 1 \ No newline at end of file diff --git a/wininstall/bin/jvm.ini b/wininstall/bin/jvm.ini new file mode 100644 index 0000000..099501d --- /dev/null +++ b/wininstall/bin/jvm.ini @@ -0,0 +1,2 @@ +Xms=64 +Xmx=256 \ No newline at end of file diff --git a/wininstall/libfordeployment/dt.jar b/wininstall/libfordeployment/dt.jar new file mode 100644 index 0000000..9e3a883 Binary files /dev/null and b/wininstall/libfordeployment/dt.jar differ diff --git a/wininstall/libfordeployment/tools.jar b/wininstall/libfordeployment/tools.jar new file mode 100644 index 0000000..9315923 Binary files /dev/null and b/wininstall/libfordeployment/tools.jar differ diff --git a/wininstall/script/nmsclient_shouhu.bat b/wininstall/script/nmsclient_shouhu.bat new file mode 100644 index 0000000..3f1e108 --- /dev/null +++ b/wininstall/script/nmsclient_shouhu.bat @@ -0,0 +1,77 @@ +@ECHO OFF +rem --------------------------------------------------------------------------- +rem Start ShouHu Script for the NMS Client +rem --------------------------------------------------------------------------- + +rem Guess NMSCLIENT_HOME if not defined +set "PRG_DIR=%~dp0" + + +if not "%NMSCLIENT_HOME%" == "" goto gotHome + +set "NMSCLIENT_HOME=%PRG_DIR%" +if exist "%NMSCLIENT_HOME%\bin\NMSClient.exe" goto okHome +cd /d %PRG_DIR%\.. +set "NMSCLIENT_HOME=%cd%" +cd "%PRG_DIR%" + +:gotHome +if exist "%NMSCLIENT_HOME%\bin\NMSClient.exe" goto okHome +echo The NMSCLIENT_HOME environment variable is not defined correctly +echo This environment variable is needed to run this program +goto end + +:okHome + +set "NC_TASKDIR=%1" +set "log_file=%NMSCLIENT_HOME%\temp\job.log" +echo start shouhu at: %DATE% %TIME% NC_TASKDIR:"%NC_TASKDIR%" >> "%log_file%" + +:topLoop + ping -n 50 127.0.0.1>nul + set procExist=0 + wmic process where name="NMSClient.exe" get name |findstr "NMSClient.exe">nul &&set /a procExist+=1 + echo procExist: "%procExist%" + if not "%procExist%" == "0" goto toPing + + echo Down at: %DATE% %TIME% >> "%log_file%" + + :: ---------- handler agent upgrade result + if not "%NC_TASKDIR%" == "" ( + if exist "%NC_TASKDIR%" ( + cd /d %NC_TASKDIR% + ren *.upgrade *.result >>"%log_file%" 2>&1 + cd /d %NMSCLIENT_HOME%\bin + ) + ) + + :: ---------- start NC + echo start NMSClient ... >> "%log_file%" + net start NMSClient + + :toPing + ping -n 3 127.0.0.1>nul +goto topLoop + + + + + +rem set XMS_VALUE=32 +rem set XMX_VALUE=128 +rem if exist "%NMSCLIENT_HOME%\bin\jvm.ini" ( +rem cd /d "%NMSCLIENT_HOME%\bin" +rem for /f "tokens=1,2 delims==" %%a IN (jvm.ini) Do ( +rem rem echo "Xms"=="%%a" +rem if "Xms"=="%%a" ( +rem set XMS_VALUE=%%b +rem ) +rem if "Xmx"=="%%a" ( +rem set XMX_VALUE=%%b +rem ) +rem ) +rem ) +rem set /a XMS_VALUE=%XMS_VALUE%*(1024*1024) +rem set /a XMX_VALUE=%XMX_VALUE%*(1024*1024) + +rem start "" "%NMSCLIENT_HOME%\bin\NMSClient.exe" -Jinitialheap=%XMS_VALUE% -Jmaxheap=%XMX_VALUE% \ No newline at end of file diff --git a/wininstall/script/restart.bat b/wininstall/script/restart.bat new file mode 100644 index 0000000..f174e7f --- /dev/null +++ b/wininstall/script/restart.bat @@ -0,0 +1,110 @@ +@ECHO OFF +rem --------------------------------------------------------------------------- +rem Start Script for the NMS Client +rem --------------------------------------------------------------------------- + +rem Guess NMSCLIENT_HOME if not defined +set "PRG_DIR=%~dp0" + + +if not "%NMSCLIENT_HOME%" == "" goto gotHome + +set "NMSCLIENT_HOME=%PRG_DIR%" +if exist "%NMSCLIENT_HOME%\bin\NMSClient.exe" goto okHome +cd /d %PRG_DIR%\.. +set "NMSCLIENT_HOME=%cd%" +cd "%PRG_DIR%" + +:gotHome +if exist "%NMSCLIENT_HOME%\bin\NMSClient.exe" goto okHome +echo The NMSCLIENT_HOME environment variable is not defined correctly +echo This environment variable is needed to run this program +goto end + +:okHome + +::----NMSCLIENT_TASKDIR use : modify taskresult and start shouhu +set "NMSCLIENT_TASKDIR=%NMSCLIENT_HOME%\task" +if ""%3"" == """" goto okHome2 +set "NMSCLIENT_TASKDIR=%3" +set "cd_=%3" +:loop +set "cd_=%cd_:*\=%" +set "cd_tmp=%cd_:\=%" +if not "%cd_tmp%"=="%cd_%" goto loop +call set "NMSCLIENT_TASKDIR=%%NMSCLIENT_TASKDIR:%cd_%=%%" + +:okHome2 + +echo NMSCLIENT_HOME: %NMSCLIENT_HOME% +echo NMSCLIENT_TASKDIR: %NMSCLIENT_TASKDIR% +set "wtitle=NmsClient" +set "_NAME=NMSClient.exe" + +set procExist=0 +wmic process where name="%_NAME%" get name |findstr "%_NAME%">nul &&set /a procExist+=1 +if not "%procExist%" == "0" goto stopProc +echo %wtitle% is not start, now start...... +goto copyCode + +:stopProc +echo %wtitle% is start, now restart...... + +set "shouhu_name=nmsclient_shouhu.bat" +::-------stopShouhu +set shouhuProcExist=0 +wmic process where name="cmd.exe" get CommandLine |findstr "%shouhu_name%">nul &&set /a shouhuProcExist+=1 +if not "%shouhuProcExist%" == "0" ( + echo stop shouhu process ..... + wmic process where "name='cmd.exe' and CommandLine like '%%nmsclient_shouhu.bat%%'" delete + ping -n 3 127.0.0.1>nul +) +::-------startShouhu +set shouhuProcExist=0 +wmic process where name="cmd.exe" get CommandLine |findstr "%shouhu_name%">nul &&set /a shouhuProcExist+=1 +if "%shouhuProcExist%" == "0" ( + echo start shouhu process ..... + start /b %NMSCLIENT_HOME: =" "%\script\nmsclient_shouhu.bat %NMSCLIENT_TASKDIR: =" "% >nul 2>&1 +) + +wmic process where name="%_NAME%" delete >nul +ping -n 3 127.0.0.1>nul +set stopOk=0 +wmic process where name="%_NAME%" get name |findstr "%_NAME%">nul &&set /a stopOk+=1 +if not "%stopOk%" == "0" goto handleTask + +:copyCode +set copyError=0 +if ""%1"" == """" goto startProc +if ""%2"" == """" goto startProc +if ""%3"" == """" goto startProc +if not ""%1"" == """" ( + if not ""%2"" == """" ( + if not ""%3"" == """" ( + xcopy /Y /I /E /F %1 %2 >>%3 2>&1 ||set /a copyError+=1 + ) else ( + xcopy /Y /I /E /F %1 %2 >nul 2>&1 ||set /a copyError+=1 + ) + rmdir /S /Q %1 >nul 2>&1 + ) +) +rem ---------- copy error +if not "%copyError%" == "0" goto handleTask + +:startProc +net start NMSClient +set startOk=0 +ping -n 3 127.0.0.1>nul +wmic process where name="%_NAME%" get name |findstr "%_NAME%">nul &&set /a startOk+=1 +if not "%startOk%" == "1" goto handleTask +goto end + +:handleTask +if "%NMSCLIENT_TASKDIR%" == "" goto end +if not exist "%NMSCLIENT_TASKDIR%" goto end +cd /d %NMSCLIENT_TASKDIR% +ren *.upgrade *.result>nul 2>&1 +cd /d %NMSCLIENT_HOME%\bin +goto end + +:end \ No newline at end of file