package com.ucar.datalink.manager.core.web.controller.task; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.google.common.collect.Lists; import com.ucar.datalink.biz.service.*; import com.ucar.datalink.biz.utils.AuditLogOperType; import com.ucar.datalink.biz.utils.AuditLogUtils; import com.ucar.datalink.common.errors.DatalinkException; import com.ucar.datalink.common.errors.ValidationException; import com.ucar.datalink.domain.Parameter; import com.ucar.datalink.domain.media.MediaSourceInfo; import com.ucar.datalink.domain.media.MediaSourceType; import com.ucar.datalink.domain.media.parameter.hbase.HBaseMediaSrcParameter; import com.ucar.datalink.domain.media.parameter.zk.ZkMediaSrcParameter; import com.ucar.datalink.domain.plugin.PluginWriterParameter; import com.ucar.datalink.domain.plugin.reader.hbase.HBaseReaderParameter; import com.ucar.datalink.domain.plugin.writer.es.EsWriterParameter; import com.ucar.datalink.domain.plugin.writer.hbase.HBaseWriterParameter; import com.ucar.datalink.domain.plugin.writer.hdfs.CommitMode; import com.ucar.datalink.domain.plugin.writer.hdfs.HdfsWriterParameter; import com.ucar.datalink.domain.plugin.writer.kafka.PartitionMode; import com.ucar.datalink.domain.plugin.writer.kafka.SerializeMode; import com.ucar.datalink.domain.plugin.writer.rdbms.RdbmsWriterParameter; import com.ucar.datalink.domain.task.TargetState; import com.ucar.datalink.domain.task.TaskInfo; import com.ucar.datalink.domain.task.TaskStatus; import com.ucar.datalink.domain.task.TaskType; import com.ucar.datalink.manager.core.coordinator.ClusterState; import com.ucar.datalink.manager.core.coordinator.GroupMetadataManager; import com.ucar.datalink.manager.core.server.ManagerConfig; import com.ucar.datalink.manager.core.server.ServerContainer; import com.ucar.datalink.manager.core.web.annotation.AuthIgnore; import com.ucar.datalink.manager.core.web.dto.task.HBaseTaskModel; import com.ucar.datalink.manager.core.web.dto.task.TaskModel; import com.ucar.datalink.manager.core.web.dto.task.TaskView; import com.ucar.datalink.manager.core.web.util.AuditLogInfoUtil; import com.ucar.datalink.manager.core.web.util.Page; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import java.text.SimpleDateFormat; import java.util.*; import java.util.stream.Collectors; /** * Created by lubiao on 2017/6/15. */ @Controller @RequestMapping(value = "/hbaseTask") public class HBaseTaskController extends BaseTaskController { public static Logger logger = LoggerFactory.getLogger(HBaseTaskController.class); @Autowired TaskConfigService taskService; @Autowired GroupService groupService; @Autowired MediaService mediaService; @Autowired TaskStatusService taskStatusService; @Autowired MediaSourceService mediaSourceService; @RequestMapping(value = "/hbaseTaskList") public ModelAndView hbaseTaskList() { ModelAndView mav = new ModelAndView("task/hbaseTaskList"); List<TaskInfo> taskList = taskService.getList(); mav.addObject("taskList", CollectionUtils.isEmpty(taskList) ? taskList : taskList.stream().filter(t -> t.getTaskType() == TaskType.HBASE).collect(Collectors.toList())); mav.addObject("groupList", groupService.getAllGroups()); mav.addObject("mediaSourceList", mediaService.getMediaSourcesByTypes(MediaSourceType.HBASE)); return mav; } @RequestMapping(value = "/initHbaseTaskList") @ResponseBody public Page<TaskView> initHbaseTaskList(@RequestBody Map<String, String> map) { Page<TaskView> page = new Page<>(map); PageHelper.startPage(page.getPageNum(), page.getLength()); Long readerMediaSourceId = Long.valueOf(map.get("readerMediaSourceId")); Long groupId = Long.valueOf(map.get("groupId")); Long id = Long.valueOf(map.get("id")); List<TaskInfo> taskInfos = taskService.listTasksForQueryPage( readerMediaSourceId == -1L ? null : readerMediaSourceId, groupId == -1L ? null : groupId, id == -1L ? null : id, TaskType.HBASE); List<TaskView> taskViews = taskInfos.stream().map(i -> { TaskView view = new TaskView(); view.setId(i.getId()); view.setTaskName(i.getTaskName()); view.setTaskDesc(i.getTaskDesc()); view.setTargetState(i.getTargetState()); view.setGroupId(i.getGroupId()); return view; }).collect(Collectors.toList()); GroupMetadataManager groupManager = ServerContainer.getInstance().getGroupCoordinator().getGroupManager(); ClusterState clusterState = groupManager.getClusterState(); Map<Long, Long> taskWorkerMap = clusterState.getTaskWorkerMapping(); taskViews.forEach(t -> t.setWorkerId(taskWorkerMap.get(t.getId()))); Collection<TaskStatus> allStatus = taskStatusService.getAll(); allStatus.stream().forEach(s -> taskViews.forEach(t -> { if (t.getId().toString().equals(s.getId())) { t.setListenedState(s.getState()); } })); //为View设置Position、status相关属性 taskViews.stream().forEach(i -> { i.setCurrentTimeStamp(null); i.setCurrentLogFile(null); i.setCurrentLogPosition(null); //启动时间 TaskStatus taskStatus = taskStatusService.getStatus(i.getId().toString()); if (taskStatus != null) { String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(taskStatus.getStartTime())); i.setStartTime(time); } else { i.setStartTime(""); } }); PageInfo<TaskInfo> pageInfo = new PageInfo<>(taskInfos); page.setDraw(page.getDraw()); page.setAaData(taskViews); page.setRecordsTotal((int) pageInfo.getTotal()); page.setRecordsFiltered(page.getRecordsTotal()); return page; } @RequestMapping(value = "/toAddHbaseTask") public ModelAndView toAddHbaseTask() { ModelAndView mav = new ModelAndView("task/hbaseTaskAdd"); HBaseTaskModel hbaseTaskModel = new HBaseTaskModel( new TaskModel.TaskBasicInfo(null, null, null, null, null), getWriterParameters(), groupService.getAllGroups(), TargetState.getAllStates(), mediaService.getMediaSourcesByTypes(MediaSourceType.HBASE), buildZkMediaSources(), PluginWriterParameter.RetryMode.getAllModes(), RdbmsWriterParameter.SyncMode.getAllModes(), new HBaseReaderParameter(), CommitMode.getAllCommitModes(), SerializeMode.getAllSerializeModes(), PartitionMode.getAllPartitionModes(), "" ); mav.addObject("taskModel", hbaseTaskModel); return mav; } @RequestMapping(value = "/doAddHbaseTask") @ResponseBody public synchronized String doAddHBaseTask(@RequestBody HBaseTaskModel hbaseTaskModel) { try { checkRequired(hbaseTaskModel); checkZNode(hbaseTaskModel); TaskInfo leaderTask = getLeaderTask(hbaseTaskModel); if (leaderTask != null) { checkWriter(leaderTask, hbaseTaskModel); } TaskInfo taskInfo = new TaskInfo(); taskInfo.setGroupId(hbaseTaskModel.getTaskBasicInfo().getGroupId()); taskInfo.setTaskName(hbaseTaskModel.getTaskBasicInfo().getTaskName()); taskInfo.setTaskDesc(hbaseTaskModel.getTaskBasicInfo().getTaskDesc()); taskInfo.setTargetState(hbaseTaskModel.getTaskBasicInfo().getTargetState()); taskInfo.setReaderMediaSourceId(hbaseTaskModel.getHbaseReaderParameter().getMediaSourceId()); taskInfo.setTaskType(TaskType.HBASE); taskInfo.setTaskReaderParameter(hbaseTaskModel.getHbaseReaderParameter().toJsonString()); taskInfo.setTaskWriterParameter(Parameter.listToJsonString( hbaseTaskModel.getWriterParameterMap().entrySet() .stream() .map(i -> i.getValue()) .collect(Collectors.toList())) ); taskInfo.setTaskParameter("{}"); taskInfo.setLeaderTaskId(leaderTask == null ? null : leaderTask.getId()); taskInfo.setIsLeaderTask(isLeaderTask(hbaseTaskModel)); taskService.addTask(taskInfo); AuditLogUtils.saveAuditLog(AuditLogInfoUtil.getAuditLogInfoFromTaskInfo(taskInfo, "004010203", AuditLogOperType.insert.getValue())); } catch (Exception e) { logger.error("Add HbaseTask Failed.", e); return "操作失败:" + e.getMessage(); } return "success"; } @RequestMapping(value = "/toUpdateHbaseTask") public ModelAndView toUpdateHbaseTask(Long id) { ModelAndView mav = new ModelAndView("task/hbaseTaskUpdate"); TaskInfo taskInfo = taskService.getTask(id); Map<String, PluginWriterParameter> writerParameterMap = getWriterParameters(); taskInfo.getTaskWriterParameterObjs().forEach(i -> writerParameterMap.put(i.getPluginName(), i)); HBaseTaskModel hbaseTaskModel = new HBaseTaskModel( new TaskModel.TaskBasicInfo( id, taskInfo.getTaskName(), taskInfo.getTaskDesc(), taskInfo.getTargetState(), taskInfo.getGroupId() ), writerParameterMap, groupService.getAllGroups(), TargetState.getAllStates(), mediaService.getMediaSourcesByTypes(MediaSourceType.HBASE), buildZkMediaSources(), PluginWriterParameter.RetryMode.getAllModes(), RdbmsWriterParameter.SyncMode.getAllModes(), (HBaseReaderParameter) taskInfo.getTaskReaderParameterObj(), CommitMode.getAllCommitModes(), SerializeMode.getAllSerializeModes(), PartitionMode.getAllPartitionModes(), taskInfo.isLeaderTask() ? "1" : "0" ); hbaseTaskModel.setCurrentWriters(taskInfo.getTaskWriterParameterObjs().stream().collect(Collectors.toMap(PluginWriterParameter::getPluginName, i -> "1"))); mav.addObject("taskModel", hbaseTaskModel); return mav; } @RequestMapping(value = "/doUpdateHbaseTask") @ResponseBody public synchronized String doUpdateHbaseTask(@RequestBody HBaseTaskModel hbaseTaskModel, String sync) { try { checkRequired(hbaseTaskModel); checkZNode(hbaseTaskModel); TaskInfo taskInfo = taskService.getTask(hbaseTaskModel.getTaskBasicInfo().getId()); if (!taskInfo.isLeaderTask()) { TaskInfo leaderTask = taskService.getTask(taskInfo.getLeaderTaskId()); checkWriter(leaderTask, hbaseTaskModel); } taskInfo.setId(hbaseTaskModel.getTaskBasicInfo().getId()); taskInfo.setGroupId(hbaseTaskModel.getTaskBasicInfo().getGroupId()); taskInfo.setTaskName(hbaseTaskModel.getTaskBasicInfo().getTaskName()); taskInfo.setTaskDesc(hbaseTaskModel.getTaskBasicInfo().getTaskDesc()); taskInfo.setTargetState(hbaseTaskModel.getTaskBasicInfo().getTargetState()); taskInfo.setReaderMediaSourceId(hbaseTaskModel.getHbaseReaderParameter().getMediaSourceId()); taskInfo.setTaskReaderParameter(hbaseTaskModel.getHbaseReaderParameter().toJsonString()); taskInfo.setTaskWriterParameter(Parameter.listToJsonString( hbaseTaskModel.getWriterParameterMap().entrySet() .stream() .map(i -> i.getValue()) .collect(Collectors.toList())) ); taskService.updateTask(taskInfo, sync); AuditLogUtils.saveAuditLog(AuditLogInfoUtil.getAuditLogInfoFromTaskInfo(taskInfo, "004010205", AuditLogOperType.update.getValue())); } catch (Exception e) { logger.error("Update HbaseTask Failed.", e); return "操作失败:" + e.getMessage(); } return "success"; } @RequestMapping(value = "/deleteHbaseTask") @ResponseBody public String deleteHbaseTask(HttpServletRequest request) { try { Long id = Long.valueOf(request.getParameter("id")); TaskInfo taskInfo = taskService.getTask(id); taskService.deleteTask(id); AuditLogUtils.saveAuditLog(AuditLogInfoUtil.getAuditLogInfoFromTaskInfo(taskInfo , "004010206", AuditLogOperType.delete.getValue())); } catch (Exception e) { logger.error("Delete HbaseTask Failed.", e); return "操作失败:" + e.getMessage(); } return "success"; } @RequestMapping(value = "/getReplZnodeParent") @ResponseBody @AuthIgnore public Map<String, Object> getListenerGroup(Long mediaSourceId) { Map<String, Object> map = new HashMap<>(); MediaSourceInfo hbaseMediaSource = mediaSourceService.getById(mediaSourceId); String znodeParent = ((HBaseMediaSrcParameter) hbaseMediaSource.getParameterObj()).getZnodeParent(); String group = "/hrdl_" + mediaSourceId + "_" + znodeParent.replace("/", ""); map.put("replZnodeParent", group); return map; } @RequestMapping(value = "/pauseHbaseTask") @ResponseBody public String pauseHbaseTask(HttpServletRequest request) { try { Long id = Long.valueOf(request.getParameter("id")); taskService.pauseTask(id); TaskInfo taskInfo = taskService.getTask(id); AuditLogUtils.saveAuditLog(AuditLogInfoUtil.getAuditLogInfoFromTaskInfo(taskInfo , "004010207", AuditLogOperType.other.getValue())); } catch (Exception e) { logger.error("Pause HbaseTask Failed.", e); return "操作失败:" + e.getMessage(); } return "success"; } @RequestMapping(value = "/resumeHbaseTask") @ResponseBody public String resumeHbaseTask(HttpServletRequest request) { try { Long id = Long.valueOf(request.getParameter("id")); taskService.resumeTask(id); TaskInfo taskInfo = taskService.getTask(id); AuditLogUtils.saveAuditLog(AuditLogInfoUtil.getAuditLogInfoFromTaskInfo(taskInfo , "004010208", AuditLogOperType.other.getValue())); } catch (Exception e) { logger.error("Pause HbaseTask Failed.", e); return "操作失败:" + e.getMessage(); } return "success"; } @RequestMapping(value = "/restartHbaseTask") @ResponseBody public String restartHbaseTask(HttpServletRequest request) { try { String id = request.getParameter("id"); sendRestartCommand(id, null); TaskInfo taskInfo = taskService.getTask(Long.valueOf(id)); AuditLogUtils.saveAuditLog(AuditLogInfoUtil.getAuditLogInfoFromTaskInfo(taskInfo , "004010209", AuditLogOperType.other.getValue())); } catch (Exception e) { logger.error("Pause HbaseTask Failed.", e); return "操作失败:" + e.getMessage(); } return "success"; } private Map<String, PluginWriterParameter> getWriterParameters() { return Lists.newArrayList(new RdbmsWriterParameter(), new EsWriterParameter(), new HdfsWriterParameter(), new HBaseWriterParameter()) .stream() .collect(Collectors.toMap(PluginWriterParameter::getPluginName, i -> i)); } private List<MediaSourceInfo> buildZkMediaSources() { List<MediaSourceInfo> list = mediaService.getMediaSourcesByTypes(MediaSourceType.ZOOKEEPER); return list == null ? Lists.newArrayList() : list.stream(). filter(i -> ((ZkMediaSrcParameter) i.getParameterObj()).getServers().equals(ManagerConfig.current().getZkServer())) .collect(Collectors.toList()); } private boolean isLeaderTask(HBaseTaskModel taskModel) { List<TaskInfo> list = taskService.getTasksByReaderMediaSourceId(taskModel.getHbaseReaderParameter().getMediaSourceId()); if (CollectionUtils.isNotEmpty(list)) { boolean hasLeader = list.stream().filter(i -> { HBaseReaderParameter parameter = (HBaseReaderParameter) i.getTaskReaderParameterObj(); return parameter.getReplZkMediaSourceId().equals(taskModel.getHbaseReaderParameter().getReplZkMediaSourceId()) && parameter.getReplZnodeParent().equals(taskModel.getHbaseReaderParameter().getReplZnodeParent()) && i.isLeaderTask(); }).findFirst().isPresent(); return !hasLeader; } return true; } private TaskInfo getLeaderTask(HBaseTaskModel taskModel) { List<TaskInfo> list = taskService.getTasksByReaderMediaSourceId(taskModel.getHbaseReaderParameter().getMediaSourceId()); if (CollectionUtils.isNotEmpty(list)) { List<TaskInfo> tasksOfThisPeer = list.stream().filter(i -> { HBaseReaderParameter parameter = (HBaseReaderParameter) i.getTaskReaderParameterObj(); return parameter.getReplZkMediaSourceId().equals(taskModel.getHbaseReaderParameter().getReplZkMediaSourceId()) && parameter.getReplZnodeParent().equals(taskModel.getHbaseReaderParameter().getReplZnodeParent()); }).collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(tasksOfThisPeer)) { List<TaskInfo> leaderTasks = tasksOfThisPeer.stream().filter(i -> i.isLeaderTask()).collect(Collectors.toList()); if (leaderTasks.size() > 1) { throw new ValidationException(String.format("发现[%s]下的Task-Leader的个数大于1,程序可能出现了bug,请排查。", taskModel.getHbaseReaderParameter().getReplZnodeParent())); } else if (leaderTasks.size() < 1) { throw new ValidationException(String.format("发现[%s]下的Task-Leader的个数小于1,程序可能出现了bug,请排查。", taskModel.getHbaseReaderParameter().getReplZnodeParent())); } else { return leaderTasks.get(0); } } } return null; } private void checkRequired(HBaseTaskModel taskModel) { if (StringUtils.isBlank(taskModel.getTaskBasicInfo().getTaskName())) { throw new RuntimeException("Task名称为必输项"); } if (StringUtils.isBlank(taskModel.getTaskBasicInfo().getTaskDesc())) { throw new RuntimeException("Task描述为必输项"); } if (taskModel.getWriterParameterMap() == null || taskModel.getWriterParameterMap().isEmpty()) { throw new RuntimeException("请至少选择一个Writer"); } if (taskModel.getHbaseReaderParameter().getMediaSourceId() == null) { throw new RuntimeException("关联数据源为必输项"); } if (taskModel.getHbaseReaderParameter().getReplZkMediaSourceId() == null) { throw new RuntimeException("Repl-Zk数据源为必输项"); } if (StringUtils.isBlank(taskModel.getHbaseReaderParameter().getReplZnodeParent())) { throw new RuntimeException("ReplZnodeParent为必输项"); } } private void checkZNode(HBaseTaskModel taskModel) { List<TaskInfo> taskInfos = taskService.getTasksByType(TaskType.HBASE); if (CollectionUtils.isNotEmpty(taskInfos)) { taskInfos.stream().forEach(t -> { HBaseReaderParameter parameter = (HBaseReaderParameter) t.getTaskReaderParameterObj(); Long hbaseId = taskModel.getHbaseReaderParameter().getMediaSourceId(); Long replZkMediaSourceId = taskModel.getHbaseReaderParameter().getReplZkMediaSourceId(); String replZnodeParent = taskModel.getHbaseReaderParameter().getReplZnodeParent(); if (replZkMediaSourceId.equals(parameter.getReplZkMediaSourceId()) && replZnodeParent.equals(parameter.getReplZnodeParent()) && !hbaseId.equals(t.getReaderMediaSourceId())) { throw new ValidationException( String.format("在ID为[%s]的Zookeeper集群上,名称为[%s]的ReplZnodeParent已经被Hbase[id=%s]使用,请为Hbase[id=%s]选择其它名称!", replZkMediaSourceId, replZnodeParent, t.getReaderMediaSourceId(), hbaseId) ); } }); } } private void checkWriter(TaskInfo leaderTask, HBaseTaskModel hbaseTaskModel) { List<PluginWriterParameter> leaderWriterList = leaderTask.getTaskWriterParameterObjs(); Map<String, PluginWriterParameter> writerParameterMap = hbaseTaskModel.getWriterParameterMap(); if (leaderWriterList.size() != writerParameterMap.size()) { throw new DatalinkException("follower task必须和leader task的writer保持一致!"); } for (Map.Entry<String, PluginWriterParameter> entry : writerParameterMap.entrySet()) { PluginWriterParameter pluginWriterParameter = entry.getValue(); String pluginName = pluginWriterParameter.getPluginName(); boolean flag = false; for (PluginWriterParameter leaderWriter : leaderWriterList) { if (pluginName.equals(leaderWriter.getPluginName())) { flag = true; break; } } if (!flag) { throw new DatalinkException("follower task必须和leader task的writer保持一致!"); } } } }