/**
* Tencent is pleased to support the open source community by making MSEC available.
*
* Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the GNU General Public License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may
* obtain a copy of the License at
*
* https://opensource.org/licenses/GPL-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
package beans.service;
import beans.dbaccess.LibraryFile;
import beans.dbaccess.SecondLevelServiceConfigTag;
import beans.dbaccess.SharedobjectTag;
import beans.request.ReleasePlan;
import ngse.org.*;
import org.apache.log4j.Logger;
import javax.servlet.ServletContext;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Administrator on 2016/2/16.
* 打包一个tar文件,里面包含要发布的完整信息
*/
public class PackReleaseFile implements Runnable {
ReleasePlan plan;
ServletContext servletContext;//用来读取war包里的spp.tar
public PackReleaseFile(ReleasePlan p, ServletContext context)
{
servletContext = context;
plan = p;
}
private ArrayList<LibraryFile> getLibraryFilesFromDB(String flsn, String slsn)
{
Logger logger = Logger.getLogger(PackReleaseFile.class);
DBUtil util = new DBUtil();
if (util.getConnection() == null)
{
return null;
}
try {
String sql = "select file_name from t_library_file where first_level_service_name=? and second_level_service_name=?";
List<Object> params = new ArrayList<Object>();
params.add(flsn);
params.add(slsn);
ArrayList<LibraryFile> ret = util.findMoreRefResult(sql, params, LibraryFile.class);
logger.info("get library file list:"+ret.size());
return ret;
}
catch (Exception e)
{
e.printStackTrace();
logger.error(e.getMessage());
return null;
}
finally {
util.releaseConn();
}
}
private boolean copyFile(File frm, File to)
{
try {
FileInputStream in = new FileInputStream(frm);
FileOutputStream out = new FileOutputStream(to);
byte[] buf = new byte[1024*8];
while (true)
{
int len = in.read(buf);
if (len <= 0)
{
break;
}
out.write(buf, 0, len);
}
in.close();
out.close();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
private void updateProcessInfo(String plan_id, String info)
{
Logger logger = Logger.getLogger(PackReleaseFile.class);
DBUtil util = new DBUtil();
if (util.getConnection() == null) {
return;
}
try {
String sql = "update t_release_plan set backend_task_status = ? where plan_id=?";
List<Object> params = new ArrayList<Object>();
params.add(info);
params.add(plan_id);
logger.info("update progress status:"+info);
int updNum = util.updateByPreparedStatement(sql, params);
if (updNum != 1) {
return;
}
} catch (Exception e) {
e.printStackTrace();
logger.error(e.getMessage());
return;
} finally {
util.releaseConn();
}
}
private void copyCnfFile(String baseDir) throws Exception
{
Logger logger = Logger.getLogger(PackReleaseFile.class);
String destFile = baseDir+File.separator+"etc"+File.separator+"config.ini";
String srcFile = SecondLevelServiceConfigTag.getConfigFileName(plan.getFirst_level_service_name(),
plan.getSecond_level_service_name(), plan.getConfig_tag());
if (!copyFile(new File(srcFile), new File(destFile)))
{
throw new Exception("failed to copy file:"+srcFile+" "+destFile);
}
}
private void copyLibraryFile(String baseDir) throws Exception
{
Logger logger = Logger.getLogger(PackReleaseFile.class);
ArrayList<LibraryFile> libraryFiles = getLibraryFilesFromDB(plan.getFirst_level_service_name(), plan.getSecond_level_service_name());
if (libraryFiles == null) {throw new Exception( "getLibraryFilesFromDB() failed");}
for (int i = 0; i < libraryFiles.size(); i++) {
String destFile = baseDir+"/bin/lib/"+libraryFiles.get(i).getFile_name();
String srcFile = LibraryFile.getLibraryFileName(plan.getFirst_level_service_name(),
plan.getSecond_level_service_name(), libraryFiles.get(i).getFile_name());
if (!copyFile(new File(srcFile), new File(destFile)))
{
throw new Exception("failed to copy file:"+srcFile+" "+destFile);
}
}
}
private void copySharedobject(String baseDir, String dev_lang) throws Exception
{
Logger logger = Logger.getLogger(PackReleaseFile.class);
String suffix = "so";//不管什么语言,一开始都是用.so文件先存着的
String destFile = "";
if (dev_lang.equals("c++"))
{
destFile = baseDir+File.separator+"bin"+File.separator+"msec.so";
}
else if (dev_lang.equals("java"))
{
destFile = baseDir+File.separator+"bin"+File.separator+"msec.jar";
}
else if (dev_lang.equals("php"))
{
destFile = baseDir+File.separator+"bin"+File.separator+"msec.tgz";
}
else if (dev_lang.equals("python"))
{
destFile = baseDir+File.separator+"bin"+File.separator+"msec_py.tgz";
}
String srcFile = SharedobjectTag.getSharedobjectName(plan.getFirst_level_service_name(),
plan.getSecond_level_service_name(), plan.getSharedobject_tag(), suffix);
if (!copyFile(new File(srcFile), new File(destFile)))
{
throw new Exception("failed to copy file:"+srcFile+" "+destFile);
}
// delete bin/python director if necessary, it is so big
if (dev_lang.equals("php") || dev_lang.equals("c++"))
{
String[] cmds = new String[3];
cmds[0] = "rm";
cmds[1] = "-rf";
cmds[2] = baseDir+File.separator+"bin"+File.separator+"python";
StringBuffer stringBuffer = new StringBuffer();
Tools.runCommand(cmds, stringBuffer, true);
logger.info("rm python result:"+stringBuffer.toString());
}
}
private void switchPlanStatus(String plan_id, boolean success)
{
Logger logger = Logger.getLogger(PackReleaseFile.class);
DBUtil util = new DBUtil();
if (util.getConnection() == null)
{
return;
}
String status = "created successfully";
if (!success)
{
status = "failed to create";
}
try {
String sql = "update t_release_plan set status = ? where plan_id=?";
List<Object> params = new ArrayList<Object>();
params.add(status);
params.add(plan_id);
logger.info("update plan status:"+status);
int updNum = util.updateByPreparedStatement(sql, params);
if (updNum != 1) {
return;
}
}
catch (Exception e)
{
e.printStackTrace();
logger.error(e.getMessage());
return;
}
finally {
util.releaseConn();
}
}
private void mktar(String baseDir, String tarFileName) throws Exception
{
Logger logger = Logger.getLogger(PackReleaseFile.class);
TarUtil.archive(baseDir, tarFileName);
logger.info("make tar successfully." + tarFileName);
}
private void getSppFromResource(String plan_id, String baseDir) throws Exception
{
Logger logger = Logger.getLogger(PackReleaseFile.class);
//将war包资源中的spp.tar解压到目录baseDir
InputStream inputStream = servletContext.getResourceAsStream("/resource/spp.tar");
String tmpTarFile = ServletConfig.fileServerRootDir + File.separator+"tmp"+File.separator+plan_id+".tar";
File f = null;
logger.info("copy spp in resource to "+tmpTarFile);
//将资源文件拷贝到文件系统中的普通文件,并解压缩为目录baseDir
OutputStream outputStream = new FileOutputStream(tmpTarFile);
byte[] buf = new byte[10240];
int len;
while (true) {
len = inputStream.read(buf);
if (len <= 0) {
break;
}
outputStream.write(buf, 0, len);
}
outputStream.close();
inputStream.close();
//把普通文件解包到目录baseDir
TarUtil.dearchive(new File(tmpTarFile), new File(baseDir));
logger.info("dearchive file successfully. dir=" + baseDir);
//删除普通文件
new File(tmpTarFile).delete();
}
private void getJavaFrameworkFromResource(String plan_id, String baseDir) throws Exception
{
Logger logger = Logger.getLogger(PackReleaseFile.class);
//将war包资源中的spp.tar解压到目录baseDir
InputStream inputStream = servletContext.getResourceAsStream("/resource/java.tar");
String tmpTarFile = ServletConfig.fileServerRootDir + File.separator+"tmp"+File.separator+plan_id+".tar";
File f = null;
logger.info("copy java.tar in resource to " + tmpTarFile);
//将资源文件拷贝到文件系统中的普通文件,并解压缩为目录baseDir
OutputStream outputStream = new FileOutputStream(tmpTarFile);
byte[] buf = new byte[10240];
int len;
while (true) {
len = inputStream.read(buf);
if (len <= 0) {
break;
}
outputStream.write(buf, 0, len);
}
outputStream.close();
inputStream.close();
//把普通文件解包到目录baseDir
TarUtil.dearchive(new File(tmpTarFile), new File(baseDir));
logger.info("dearchive file successfully. dir=" + baseDir);
//删除普通文件
new File(tmpTarFile).delete();
}
public static String getPackedFile(String plan_id)
{
return ServletConfig.fileServerRootDir+ "/tmp/"+plan_id+".tar.gz";
}
@Override
public void run() {
int i;
Logger logger = Logger.getLogger(PackReleaseFile.class);
String baseDir = ServletConfig.fileServerRootDir+ File.separator+"tmp"+File.separator+plan.getPlan_id();
String tarFileName = baseDir +".tar";
try {
if (plan.getDev_lang().equals("c++")) {
getSppFromResource(plan.getPlan_id(), baseDir);
} else if (plan.getDev_lang().equals("java")) {
getJavaFrameworkFromResource(plan.getPlan_id(), baseDir);
} else if (plan.getDev_lang().equals("php")) {
getSppFromResource(plan.getPlan_id(), baseDir);
} else if (plan.getDev_lang().equals("python")) {
getSppFromResource(plan.getPlan_id(), baseDir);
} else {
throw new Exception("invalid dev lang");
}
updateProcessInfo(plan.getPlan_id(), "成功拷贝spp.tar...");
if (plan.getRelease_type().equals("only_config")) {//只发布配置文件
copyCnfFile(baseDir);
updateProcessInfo(plan.getPlan_id(), "成功拷贝配置文件...");
} else if (plan.getRelease_type().equals("only_library"))//只发布外部库
{
copyLibraryFile(baseDir);
updateProcessInfo(plan.getPlan_id(), "成功拷贝库文件...");
} else if (plan.getRelease_type().equals("only_sharedobject"))//只发布业务插件
{
copySharedobject(baseDir, plan.getDev_lang());
updateProcessInfo(plan.getPlan_id(), "成功拷贝业务逻辑代码...");
} else//完整的发布
{
copyCnfFile(baseDir);
updateProcessInfo(plan.getPlan_id(), "成功拷贝配置文件...");
copyLibraryFile(baseDir);
updateProcessInfo(plan.getPlan_id(), "成功拷贝库文件...");
copySharedobject(baseDir, plan.getDev_lang());
updateProcessInfo(plan.getPlan_id(), "成功拷贝业务逻辑代码...");
if (plan.getDev_lang().equals("java")) {
//执行python脚本
String[] cmd = new String[2];
String pythonScript;
String outputDir;
pythonScript = baseDir + "/create_rpc_release.py";
new File(pythonScript).setExecutable(true);
cmd[0] = pythonScript;
cmd[1] = "bin/msec.jar";
StringBuffer cmdResult = new StringBuffer();
if (Tools.runCommand(cmd, cmdResult, true) != 0) {
logger.error(cmdResult.toString());
updateProcessInfo(plan.getPlan_id(), "执行python脚本失败:" + cmdResult);
switchPlanStatus(plan.getPlan_id(), false);
return;
}
logger.info("run python script successfully.");
}
}
mktar(baseDir, tarFileName);
GzipUtil.zip(tarFileName);
updateProcessInfo(plan.getPlan_id(), "tar文件归档成功");
switchPlanStatus(plan.getPlan_id(), true);
//删除临时目录
Tools.deleteDirectory(new File(baseDir));
new File(tarFileName).delete();
} catch (Exception e) {
updateProcessInfo(plan.getPlan_id(), "Exception:" + e.getMessage());
switchPlanStatus(plan.getPlan_id(), false);
e.printStackTrace();
logger.error(e.getMessage());
return;
} finally {
new File(baseDir).delete();
}
}
}