补丁更新

package com.suteam.zsyun.job;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
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.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.apache.log4j.Logger;
import com.alibaba.fastjson.JSON;
import com.suteam.zsyun.application.model.ApplicationFilePack;
import com.suteam.zsyun.commonUtil.FileUtil;
import com.suteam.zsyun.commonUtil.HttpAuthUtil;
import com.suteam.zsyun.commonUtil.ModifyConfig;
import com.suteam.zsyun.config.Config;

/**
 * agent守护进程项目定时任务
 * 
 * @author zsyun_gsa
 *
 */
public class BasicJobUtil {
    public static Logger log = Logger.getLogger(BasicJobUtil.class);

    public static void executeTask() {
        log.info(" *****agent守护进程定时任务开始***** ");
        try {
            // 获取jar文件当前路径
            String path = System.getProperty("user.dir");
            log.info("jar文件当前路径:"+path);
            // 获取配置文件路径
            String configPath = FileUtil.getConfigPath();
            // 读取配置文件config.ini,获取版本号version_Number与当前jar文件名称
            Properties configProperty = FileUtil.getConfig(configPath + Config.configName);
            String versionNumber = configProperty.getProperty("version_Number");
            String agentName = configProperty.getProperty("agent_Name");
            // 读取配置文件es.ini,获取code
            Properties esProperty = FileUtil.getConfig(configPath + Config.esName);
            String code = esProperty.getProperty("code");
            // 读取配置文件watch.ini,获取app项目服务器地址
            Properties watchProperty = FileUtil.getConfig(configPath + Config.watchName);
            String appServer = watchProperty.getProperty("appServer");

            // 声明一个存放请求参数的map
            Map<String, String> parameterMap = new HashMap<String, String>();
            // 拼接调用app项目中的版本查询接口的url和参数
            String url = appServer + "/v1/port/appService/query/queryPatch.do";
            parameterMap.put("code", code);
            parameterMap.put("versionNumber", versionNumber);
            // 调用APP项目中版本查询接口
            log.info("调用APP项目中版本查询接口:");
            String result = HttpAuthUtil.doAuthPost(url, parameterMap);
            Map<String, Object> mapResult = (Map<String, Object>) JSON.parse(result);
            if (null != mapResult && "ok".equals(mapResult.get("result"))) {
                log.info("调用APP项目中版本查询接口,ok:");
                // 解析获取应用文件包对象
                ApplicationFilePack applicationFilePack = JSON.parseObject(String.valueOf(mapResult.get("values")),
                        ApplicationFilePack.class);
                // 判断应用文件包对象是否为空。不为空说明有要更新的agent。
                if (null != applicationFilePack) {
                    log.info("文件包对象不为空,说明有要更新的agent。");
                    // 获取版本
                    String version = applicationFilePack.getVersion();
                    log.info("获取新版本version:" + version);
                    if (!version.equals(versionNumber)) {
                        log.info("新旧版本不同。");
                        // 获取应用文件路径
                        String filePath = applicationFilePack.getFilePath();
                        log.info("新文件路径:"+filePath);
                        // 获取文件hash
                        String hash = applicationFilePack.getHash();
                        log.info("新文件hash:"+hash);
                        // 获取名称,如agent_1.2.jar
                        String name = applicationFilePack.getName();
                        log.info("新文件名称:" + name);
                        
                        // 调用下载补丁方法
                        String getHash = downLoadFromUrl(filePath, name, path);
                        if (!getHash.equals(hash)) {
                            // 将下载失败的文件删除
                            if (path.contains("/")) {
                                path += "/";
                            }
                            if (path.contains("\\")) {
                                path += "\\";
                            }
                            log.info("将下载失败的文件删除,要删除的文件为:"+path + name);
                            deleteFile(path + name);
                            // hash不同,下次定时任务重新下载
                            log.info("hash不同,下次定时任务重新下载");
                        } else {
                            log.info("新下载的jar文件与原文件hash相同。");
                            // 修改配置文件,将文件版本更新成新版本
                            log.info("修改配置文件更新版本信息:");
                            String[] keyArray = new String[2];
                            keyArray[0] = "version_Number";
                            keyArray[1] = "agent_Name";
                            String[] valueArray = new String[2];
                            valueArray[0] = version;
                            valueArray[1] = name;
                            log.info("新的版本为:" + version);
                            String fileName = "config.ini";
                            ModifyConfig.modifyConfig(keyArray, valueArray, fileName);
                            log.info("修改配置文件更新版本信息,完成。");

                            log.info("将原agent停止:");
                            if (path.contains("/")) {
                                path += "/";
                                log.info("Linux将原agent停止:");
                                String psCommander = "ps -ef|grep "+agentName;
                                log.info("查看进程指令:" + psCommander);
                                Process ps = Runtime.getRuntime().exec(new String[] { "sh", "-c", psCommander });
                                BufferedReader br = new BufferedReader(new InputStreamReader(ps.getInputStream()));
                                StringBuffer sb = new StringBuffer();
                                String line;
                                while ((line = br.readLine()) != null) {
                                    sb.append(line).append("\n");
                                }
                                String ret = sb.toString();
                                // 将获取结果去除回车拆分
                                String[] resultStr = ret.split("\n");
                                for (int j = 0; j < resultStr.length; j++) {
                                    String s = resultStr[j];
                                    // 去除tab键
                                    s = s.replace("    ", " ");
                                    log.info("去除tab键:" + s);
                                    // 将所有的多空格转成单空格
                                    s = s.replaceAll(" +", " ");
                                    log.info("将所有的多空格转成单空格:" + s);
                                    if (s.startsWith(" ")) {
                                        // 将第一个空格截取去除
                                        s = s.substring(1, s.length());
                                        log.info("将第一个空格截取去除:" + s);
                                    }
                                    // 将数据以空格拆分:root 16608 4888 0 15:08 pts/1
                                    // 00:00:47 java -jar agent.jar
                                    String[] retStr = s.split(" ");
                                    log.info("将数据以空格拆分:" + s);
                                    // 获取进程结果的最后一个数据(所下达的指令为何)
                                    String cmdCommander = "";
                                    for (int i = 7; i < retStr.length; i++) {
                                        cmdCommander = cmdCommander + retStr[i];
                                    }
                                    log.info("logCode进程结果的最后一个数据:" + cmdCommander);
                                    log.info("pid为:" + retStr[1]);
                                    if (cmdCommander.contains("java-jar")) {
                                        // 包含文件名,说明这个进程为要杀死的agent进程。获取进程的pid(第二个数据)。
                                        String pid = retStr[1];
                                        log.info("pid为:" + retStr[1]);
                                        // 获取cp进程的标识号,拼接杀进程指令kill -9 进程标识号
                                        String killCommander = "kill -9 " + pid;
                                        // 执行杀进程指令
                                        log.info("---开始执行kill指令:" + killCommander);
                                        Runtime.getRuntime().exec(killCommander);
                                        log.info("---执行kill指令完毕。");
                                    }
                                }
                                
                                // 文件路径
                                String shfileName = path+"/restarJar.sh";
                                log.info("获取sh文件路径如下 :"+shfileName);
                                // 1.删除文件
                                deleteFile(shfileName);
                                log.info("删除文件完成。");
                                // 2.创建文件
                                createNewFile(shfileName);
                                log.info("创建文件完成。");
                                //changeParam为要追加到.sh文件的信息
                                String changeParam = "nohup java -jar /usr/agenthost/" + name +" > /usr/agenthost/logs/myout.file 2>&1 &";
                                log.info("追加到.sh文件的信息:"+ changeParam);
                                // 3.追加内容  \n代表回车换行
                                StringBuffer strBuffer = new StringBuffer();
                                strBuffer.append("#!/bin/sh\n");
                                strBuffer.append(changeParam);
                                appendMethod(shfileName, strBuffer.toString());
                                log.info("追加完成");
                                
                                log.info("执行sh文件:bash "+path+"/restarJar.sh");
                                Runtime.getRuntime().exec("bash "+path+"/restarJar.sh");
                                log.info("执行sh文件完成");
                            }
                            if (path.contains("\\")) {
                                path += "\\";
                                log.info("Windows将原agent停止:");
                                
                                // 查看Windows系统所有正在运行的java程序
                                String psCommander = "jps -l";
                                log.info("查看进程指令:" + psCommander);
                                Process ps = Runtime.getRuntime().exec(psCommander);
                                BufferedReader br = new BufferedReader(new InputStreamReader(ps.getInputStream()));
                                StringBuffer sb = new StringBuffer();
                                String line;
                                while ((line = br.readLine()) != null) {
                                    sb.append(line).append("\n");
                                }
                                String ret = sb.toString();
                                // 将获取结果去除回车拆分
                                String[] resultStr = ret.split("\n");
                                for (int j = 0; j < resultStr.length; j++) {
                                    String s = resultStr[j];
                                    // 去除tab键
                                    s = s.replace("    ", " ");
                                    log.info("去除tab键:" + s);
                                    // 将所有的多空格转成单空格
                                    s = s.replaceAll(" +", " ");
                                    log.info("将所有的多空格转成单空格:" + s);
                                    if (s.startsWith(" ")) {
                                        // 将第一个空格截取去除
                                        s = s.substring(1, s.length());
                                        log.info("将第一个空格截取去除:" + s);
                                    }
                                    // 将数据以空格拆分:root 16608 4888 0 15:08 pts/1
                                    // 00:00:47 java -jar agent.jar
                                    String[] retStr = s.split(" ");
                                    log.info("将数据以空格拆分:" + s);
                                    // 获取进程结果的最后一个数据(所下达的指令为何)
                                    if(retStr.length>1){
                                        String cmdCommander = retStr[1];
                                        log.info("logCode进程结果的最后一个数据:" + cmdCommander);
                                        if (cmdCommander.contains(agentName)) {
                                            // 包含文件名,说明这个进程为要杀死的agent进程。获取进程的pid(第二个数据)。
                                            String pid = retStr[0];
                                            log.info("pid为:" + retStr[0]);
                                            // 获取cp进程的标识号,拼接杀进程指令kill -9 进程标识号
                                            String killCommander = "TASKKILL /F /PID " + pid;
                                            // 执行杀进程指令
                                            log.info("---开始执行kill指令:" + killCommander);
                                            Runtime.getRuntime().exec(killCommander);
                                            log.info("---执行kill指令完毕。");
                                        }
                                    }
                                }
                                
                                // 重启jar文件路径
                                String shfileName = path+"\\restarJar.bat";
                                log.info("获取重启jar文件路径如下 :"+shfileName);
                                // 删除原文件
                                deleteFile(shfileName);
                                log.info("删除原文件完成。");
                                // 重新创建文件
                                createNewFile(shfileName);
                                log.info("重新创建文件完成。");
                                //changeParam为要追加到.sh文件的信息
                                String changeParam = "start javaw -jar " + name;
                                log.info("追加到.bat文件的信息:"+ changeParam);
                                // 将内容追加到重启bat文件中  \n代表回车换行
                                StringBuffer strBuffer = new StringBuffer();
                                strBuffer.append("@echo off\n");
                                strBuffer.append(changeParam+"\n");
                                strBuffer.append("success& exit\n");
                                appendMethod(shfileName, strBuffer.toString());
                                log.info("追加完成");
                                
                                log.info("执行重启jarbat文件");
                                String cmd = "cmd.exe /c   start  " + shfileName;
                                Runtime.getRuntime().exec(cmd);
                                log.info("执行重启jarbat文件完成");
                            }
                            
                        }
                    }
                }
            } else {
                log.info("获取对象为空,没有要更新的!");
            }
        } catch (Exception e) {
            log.info("agent守护进程抛出异常。");
        }
        log.info(" *****agent守护进程定时任务结束*****");
    }

    /***
     * 对文件做hash处理
     * 
     * @param filename
     * @return
     * @throws Exception
     */
    public static String getMD5Checksum(String filename) throws Exception {
        log.info("进入获取hash方法:");
        byte[] b = createChecksum(filename);
        String result = "";

        for (int i = 0; i < b.length; i++) {
            result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);// 加0x100是因为有的b[i]的十六进制只有1位
        }
        return result;
    }

    public static byte[] createChecksum(String filename) throws Exception {
        InputStream fis = new FileInputStream(filename);// 20px;">将流类型字符串转换为String类型字符串</span>

        byte[] buffer = new byte[1024];
        MessageDigest complete = MessageDigest.getInstance("MD5"); // 如果想使用SHA-1或SHA-256,则传入SHA-1,SHA-256
        int numRead;
        do {
            numRead = fis.read(buffer); // 从文件读到buffer,最多装满buffer
            if (numRead > 0) {
                complete.update(buffer, 0, numRead); // 用读到的字节进行MD5的计算,第二个参数是偏移量
            }
        } while (numRead != -1);

        fis.close();
        return complete.digest();
    }

    /**
     * 删除文件方法
     */
    public static void deleteFile(String fileName) {
        File file = new File(fileName);
        // 如果是文件,非目录
        if (file.isFile()) {
            file.delete();
        } else {
            return;
        }
    }

    /**
     * 新建文件方法
     */
    public static void createNewFile(String fileName) {
        File file = new File(fileName);
        // 如果文件不存在,新建一个文件
        if (file.isFile() && !file.exists()) {
            try {
                // 创建文件
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 追加文件方法
     */
    public static void appendMethod(String fileName, String content) {
        try {
            // 打开一个写文件器,构造函数中的第二个参数true表示以追加形式写文件
            OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(fileName, true), "GBK");
            osw.write(content);
            osw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 从网络Url中下载文件
     * 
     * @param urlStr
     * @param fileName
     * @param savePath
     * @throws IOException
     */
    public static String downLoadFromUrl(String urlStr, String fileName, String savePath) throws IOException {
        String retHash = "";
        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        // 设置超时间为3秒
        conn.setConnectTimeout(3 * 1000);
        // 防止屏蔽程序抓取而返回403错误
        conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
        // 得到输入流
        InputStream inputStream = conn.getInputStream();
        // 获取自己数组
        byte[] getData = readInputStream(inputStream);
        // 文件保存位置
        File saveDir = new File(savePath);
        if (!saveDir.exists()) {
            saveDir.mkdir();
        }
        File file = new File(saveDir + File.separator + fileName);
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(getData);
        if (fos != null) {
            fos.close();
        }
        if (inputStream != null) {
            inputStream.close();
        }
        log.info("info:" + url + " download success");
        // 下载完毕,对补丁(或agent)进行hash处理
        try {
            if (savePath.contains("/")) {
                savePath += "/";
            }
            if (savePath.contains("\\")) {
                savePath += "\\";
            }
            log.info("hash路径:" + savePath + fileName);
            retHash = getMD5Checksum(savePath + fileName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        log.info("获取的文件hash:" + retHash);
        return retHash;
    }

    /**
     * 从输入流中获取字节数组
     * 
     * @param inputStream
     * @return
     * @throws IOException
     */
    public static byte[] readInputStream(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[1024];
        int len = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while ((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        bos.close();
        return bos.toByteArray();
    }
    public static void main(String[] args) {
        try {
            String hash = getMD5Checksum("H:\\agent_v1.2.jar");
            System.out.println(hash);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
 

转载于:https://my.oschina.net/u/3037187/blog/874759

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值