package com.platform.service.thread; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.annotation.Resource; import org.apache.log4j.Logger; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import com.base.TaskOperateData; import com.platform.dao.DataInfoDao; import com.platform.dao.DataInfoMoveTmpDao; import com.platform.entities.DataInfoEntity; import com.platform.entities.DataInfoEntityMoveTmp; import com.platform.glusterfs.CheckoutMD5; import com.platform.http.gfs.CopyData; import com.platform.glusterfs.ShowData; import com.platform.utils.Bean2MapUtils; import com.platform.utils.Constant; import com.platform.utils.DateForm; import com.platform.utils.FileOperateHelper; /** 数据迁移---(该类不用了,丢弃) * @author chen * */ @Component public class ThreadMoveData{ public final static Logger log = Logger.getLogger(ThreadMoveData.class); @Resource(name = "dataInfoDao") private DataInfoDao dataInfoDao; /** * 迁移 */ CopyData copy = new CopyData(); /** * MD5校验 */ CheckoutMD5 check = new CheckoutMD5(); @Resource(name = "dataInfoMoveTmpDao") private DataInfoMoveTmpDao dataInfoMoveTmpDao; /** * 查看数据 */ ShowData show = new ShowData(); /** * : 实时更新数据库--根据查询到的 正则迁移的数据 */ public ThreadMoveData() { } //迁移数据 -- 2016-11-30后 使用 @Scheduled(fixedDelay = 4000) public void moveDataByWebGfs(){ List result = new ArrayList(); List[] subMove = new ArrayList[4]; for (int i = 0; i < 4; i++) { subMove[i] = new ArrayList(); } try { result = dataInfoMoveTmpDao.findAll(); } catch (Exception e) { log.error(e); } Map taskMap = new HashMap(); for ( DataInfoEntityMoveTmp moveE : result) { switch (moveE.getCompleteStatus()) { //待迁移 case "0": subMove[0].add(moveE); break; //正在迁移 case "1": subMove[1].add(moveE); break; //迁移完成的 case "2": subMove[2].add(moveE); break; //迁移失败 case "3": subMove[3].add(moveE); break; default: break; } } //迁移失败---不处理 status = -1:表示迁移完成,校验失败,-2:表示迁移失败 -3:表示删除失败 //迁移完成的--不处理 status = 3:表示校验成功, //正则迁移 status = 1:表示正在迁移(如果 web gfs 迁移成功 则 增加一条记录) if(subMove[1].size() > 0){ //请求进度 List list = new ArrayList(); try { list = copy.operationTask(); } catch (Exception e) { log.error("copy.operationTask()"); log.error(e); } for (TaskOperateData taskOperateData : list) { taskMap.put(FileOperateHelper.addLastLinuxSeparator(taskOperateData.getSourcePath()) + "-" + FileOperateHelper.addLastLinuxSeparator(taskOperateData.getDestPath()), taskOperateData); } for (DataInfoEntityMoveTmp moveE : subMove[1]) { TaskOperateData taskOne = taskMap.get(FileOperateHelper.addLastLinuxSeparator(moveE.getDataPath()) +"-"+FileOperateHelper.addLastLinuxSeparator(makeDstPath(moveE.getDstPath()))); if (null == taskOne) { long nowTime = new Date().getTime(); long timelong = nowTime - DateForm.string2DateBysecond(moveE.getLastTime()).getTime(); if (timelong > 1000*60*20) { try { dataInfoMoveTmpDao.update(moveE); } catch (Exception e) { log.error(e); } } continue; } moveE.setRate(taskOne.getProgress()); moveE.setLastTime(DateForm.date2StringBysecond(new Date())); if (3 == taskOne.getStatus()) { //成功 makeDataInfo(moveE); }else if(taskOne.getStatus() < 0){ //失败 moveE.setCompleteStatus("3"); try { dataInfoMoveTmpDao.update(moveE); } catch (Exception e) { log.error(e); } } } } //待迁移 status = 0:准备迁移(则开始迁移) if(subMove[0].size() > 0){ //正则迁移的 数量 int curMoveNum = subMove[1].size(); for ( DataInfoEntityMoveTmp moveE : subMove[0]) { if(curMoveNum <= Constant.moveFileMaxNum){ moveE.setLastTime(DateForm.date2StringBysecond(new Date())); //请求迁移 curMoveNum++; try { if(1==copy.copyFolder(moveE.getDataPath(), makeDstPath(moveE.getDstPath()))){ moveE.setCompleteStatus("1"); } else { moveE.setCompleteStatus("3"); } } catch (Exception e) { log.error("copy.copyFolder()"); log.error(e); } try { dataInfoMoveTmpDao.update(moveE); } catch (Exception e) { log.error(e); } } } } } //5秒 //2016-11-30后 不使用 // @Scheduled(fixedDelay = 5000) public void doSomething() { try { List result = null; //查询 表 move_data_tmp result = dataInfoMoveTmpDao.findAll(); if (null != result) { //gfs 获取size, int rsize = result.size(); boolean isNoMove = true; //该循环必须 循环每个,不能有 break; // rate:大小:假的,待换成真实比例 double realRate = 0.00; int moveFileCurrNum = 0; for (int i = 0; i < rsize; i++) { DataInfoEntityMoveTmp dataMove = result.get(i); //如果拷贝进度超过20分钟未进行-- 判断为 迁移失败。 // "1" :正在上传,0:等待 迁移, 2:成功 3:失败 long srcSizeTemp = 0; long dstSize = 0; if ("1".equals(dataMove.getCompleteStatus())) { long nowTime = new Date().getTime(); long timelong = nowTime - DateForm.string2DateBysecond(dataMove.getLastTime()).getTime(); if (timelong > 1000*60*20) { doMd5(srcSizeTemp, dstSize, dataMove); } //正在上传的个数。 moveFileCurrNum++; if (moveFileCurrNum >= Constant.moveFileMaxNum) { isNoMove = false; } // 查询大小:。//gfs 获取size, srcSizeTemp = show.getFolderSize(dataMove.getDataPath()); long srcSize = (long) (srcSizeTemp * 0.998); dstSize = show.getFolderSize(dataMove.getDstPath()); boolean isExist = false; if (srcSize < 0) { log.error(dataMove.getDataPath() + " : 路径不存在! "); isExist = true; } if (dstSize < 0) { log.error(dataMove.getDstPath() + " : 路径不存在! "); isExist = true; } if (isExist) { // 3:表示 迁移失败 dataMove.setLastTime(DateForm.date2StringBysecond(new Date())); dataMove.setCompleteStatus("3"); dataInfoMoveTmpDao.update(dataMove); continue; } if (srcSize > 0 && dstSize > 0) { realRate = (dstSize*100 / srcSize ); } if (srcSize == dstSize || realRate > 100) { realRate = 100; } if (realRate > dataMove.getRate()) { dataMove.setLastTime(DateForm.date2StringBysecond(new Date())); dataMove.setRate((int) realRate); } } if("1".equals(dataMove.getCompleteStatus()) && dataMove.getRate() > 0){ //传输完毕:进行校验 if (realRate >= 100) { //TODO doMd5(srcSizeTemp, dstSize, dataMove); dataMove.setLastTime(DateForm.date2StringBysecond(new Date())); } dataInfoMoveTmpDao.update(dataMove); } } //循环 完了, 确定没有上传的 ,没有正在上传的 if (isNoMove) { //查询 表 move_data_tmp result = dataInfoMoveTmpDao.findAll(); if (null != result) { int tmpsize = result.size(); // 上传下一个后 for (int i = 0; i < tmpsize; i++) { DataInfoEntityMoveTmp next2move = result.get(i); //如果是 待 迁移状态的 if ("0".equals(next2move.getCompleteStatus())) { //待迁移的数据 -- 开始迁移 // 末尾 含有 / Pattern pattern2 = Pattern.compile("\\d+\\/$"); String dstPath = next2move.getDstPath(); Matcher matcher2 = pattern2.matcher(dstPath); //去掉 最后 的 数字 +/ 符合 if (matcher2.find()) { String removeStr = matcher2.group(); dstPath = dstPath.replace(removeStr, ""); } //数据迁移。 copy.copyFolder(next2move.getDataPath(), dstPath); // "1" :正在上传,0:等待 迁移, 2:成功 3:失败 next2move.setCompleteStatus("1"); next2move.setLastTime(DateForm.date2StringBysecond(new Date())); //更新sql dataInfoMoveTmpDao.update(next2move); break; } } } } } Thread.sleep(Constant.update_dataInfo_sleep_time); } catch (Exception e) { System.err.println(e); } } /** md5校验 * @param srcSizeTemp * @param dstSize * @param dataMove * @throws Exception */ private void doMd5(long srcSizeTemp, long dstSize, DataInfoEntityMoveTmp dataMove) throws Exception { int difSize = (int) (srcSizeTemp-dstSize); if (difSize < 1) { difSize = 1; } Thread.sleep(10*difSize); //TODO 查看当前拷贝目录进程是否结束? // 进行MD5校验 int resl = check.checkoutMD5Folder(dataMove.getDataPath(), dataMove.getDstPath()); // 校验成功--则增加数据库记录 if(resl == 1){ try{ // 判断 迁移数据的status是否改为 2 DataInfoEntityMoveTmp movetmp = dataInfoMoveTmpDao.findById(dataMove.getId()); if(null != movetmp){ if (!"2".equals(movetmp.getCompleteStatus())) { //校验成功--修改 数据库记录-- dataMove.setCompleteStatus("2"); dataMove.setLastTime(DateForm.date2StringBysecond(new Date())); dataInfoMoveTmpDao.update(dataMove); //TODO 新增 一条数据-到-dataInfo DataInfoEntity data = (DataInfoEntity) Bean2MapUtils.convertMap( DataInfoEntity.class, Bean2MapUtils.convertBean(dataMove)); data.setDataPath(dataMove.getDstPath()); data.setVolumeIp(dataMove.getDstVolumeIp()); data.setVolumePath(dataMove.getDstVolumePath()); data.setVolumeIp(dataMove.getVolumeIp()); data.setPayResult(dataMove.getPayResult()); data.setExecResult(dataMove.getExecResult()); data.setId(0); dataInfoDao.save(data); } else { dataMove.setCompleteStatus("2"); dataMove.setLastTime(DateForm.date2StringBysecond(new Date())); dataInfoMoveTmpDao.update(dataMove); } } }catch(Exception e){ log.error(e); } } else { // 3:表示 迁移失败 dataMove.setLastTime(DateForm.date2StringBysecond(new Date())); dataMove.setCompleteStatus("3"); } } private int makeDataInfo(DataInfoEntityMoveTmp dataMove){ try{ // 判断 迁移数据的status是否改为 2 DataInfoEntityMoveTmp movetmp = dataInfoMoveTmpDao.findById(dataMove.getId()); if(null != movetmp){ if (!"2".equals(movetmp.getCompleteStatus())) { //校验成功--修改 数据库记录-- dataMove.setCompleteStatus("2"); dataMove.setLastTime(DateForm.date2StringBysecond(new Date())); dataInfoMoveTmpDao.update(dataMove); //TODO 新增 一条数据-到-dataInfo DataInfoEntity data = (DataInfoEntity) Bean2MapUtils.convertMap( DataInfoEntity.class, Bean2MapUtils.convertBean(dataMove)); data.setDataPath(dataMove.getDstPath()); if (null == dataMove.getDstVolumeIp()) { data.setVolumeIp("localhost"); }else { data.setVolumeIp(dataMove.getDstVolumeIp()); } // volume路径,,没有传入 if (null == dataMove.getDstVolumePath()) { data.setVolumePath(dataMove.getDstPath()); }else { data.setVolumePath(dataMove.getDstVolumePath()); } data.setPayResult(dataMove.getPayResult()); data.setExecResult(dataMove.getExecResult()); data.setId(0); try { dataInfoDao.save(data); } catch (Exception e) { log.error(e); dataMove.setCompleteStatus("1"); dataInfoMoveTmpDao.update(dataMove); } } }else { dataInfoMoveTmpDao.update(dataMove); } }catch(Exception e){ log.error(e); } return 1; } /** 去掉 最后 的 数字 +/ * @param dstPath * @return */ private String makeDstPath(String dstPath) { // 末尾 含有 数字 + / Pattern pattern2 = Pattern.compile("\\d+\\/$"); Matcher matcher2 = pattern2.matcher(dstPath); //去掉 最后 的 数字 +/ 符合 if (matcher2.find()) { String removeStr = matcher2.group(); dstPath = dstPath.replace(removeStr, ""); } return dstPath; } }