package org.infosec.ismp.manager.agent; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.Externalizable; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectInputStream; import java.io.ObjectOutput; import java.io.ObjectOutputStream; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import org.apache.commons.lang.StringUtils; import org.infosec.ismp.eventd.sender.EventSender; import org.infosec.ismp.manager.agent.task.AgentTodoTask; import org.infosec.ismp.manager.agent.task.AgentTodoTask.AgentTodoType; import org.infosec.ismp.model.event.Event; import org.infosec.ismp.util.ThreadCategory; class AgentCompSnapShot implements Externalizable { // 标识Agent是否重启,重启后uuid不一样 private final String agentId; private String uuid; protected InetAddress ipAddr; protected int port; private boolean active = false; private final AgentComponent m_agent; /** * 需要发送到远端的工作 */ private List<AgentTodoTask> m_todoTasks = new LinkedList<AgentTodoTask>(); /** * 已经发送到远程Agent的工作 */ private List<AgentTodoTask> m_doneTasks = new LinkedList<AgentTodoTask>(); private final File tempFile; /** * * @param agentComponent */ public AgentCompSnapShot(AgentComponent agentComponent, File file) { m_agent = agentComponent; this.agentId = agentComponent.getAgentId(); this.tempFile = file; if (tempFile.exists()) { read(); } } private void checkFile() { if (tempFile != null) { File file = tempFile.getParentFile(); if (!file.exists()) { boolean flag = file.mkdir(); log().warn("创建文件:" + flag); } } } protected void saveToFile() { checkFile(); ObjectOutputStream out = null; try { FileOutputStream fout = new FileOutputStream(tempFile); out = new ObjectOutputStream(new BufferedOutputStream(fout)); writeExternal(out); out.flush(); } catch (Throwable e) { log().error("序列化AgentSnapShot出错 :", e); } finally { if (out != null) { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } } protected void readImage() { if (tempFile.exists() && !tempFile.isDirectory()) { read(); } } /** * 初始化从序列化文件读取内容 */ protected void read() { ObjectInputStream in = null; try { FileInputStream fin = new FileInputStream(tempFile); in = new ObjectInputStream(new BufferedInputStream(fin)); readExternal(in); } catch (Throwable e) { log().error("反序列化AgentSnapShot出错 :", e); } finally { if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 序列化时使用 */ @Override public void writeExternal(ObjectOutput out) throws IOException { log().info("快照存盘前信息:uuid is : " + uuid); log().info("存盘前已完成任务数: " + m_doneTasks.size()); log().info("存盘前未完成任务数: " + m_todoTasks.size()); out.writeUTF(agentId); out.writeUTF(uuid); out.writeObject(m_todoTasks); out.writeObject(m_doneTasks); } /** * 反序列化使用 */ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { String agentId = in.readUTF(); if (!this.agentId.equals(agentId)) { throw new RuntimeException("文件内容中AgentId发生变化,文件中agentId是" + agentId + "数据库中agentId是" + this.agentId); } uuid = in.readUTF(); List<AgentTodoTask> tasks = (List<AgentTodoTask>) in.readObject(); m_todoTasks.addAll(tasks); tasks = (List<AgentTodoTask>) in.readObject(); m_doneTasks.addAll(tasks); } // public String getUuid() { // return this.uuid; // } public void register(String uuid, String ipaddr, int port) { boolean flag = true; try { ipAddr = InetAddress.getByName(ipaddr); } catch (UnknownHostException e) { flag = false; log().fatal("agent注册的地址信息错误,注册地址是:" + ipaddr, e); } if (port < 0 || port > 65535) { flag = false; log().fatal("agent注册的端口信息错误,注册端口是:" + port); } else { this.port = port; } String trimUuid = StringUtils.trimToNull(uuid); if (trimUuid == null) { flag = false; log().fatal("agent注册的UUID信息错误,注册UUID是:" + uuid); } if (flag) {// 注册成功 setActive(true); if (uuid.equals(this.uuid)) {// 相同UUID log().info("发送未完成工作"); sendTodoTask();// 将发送未完成的工作 } else {// 不相同UUID,远程Agent重启 log().info("重置服务器工作"); this.uuid = uuid; reset(); sendTodoTask(); } } saveToFile(); } private void sendTodoTask() { log().info("未发送任务个数为:" + m_todoTasks.size()); synchronized (m_todoTasks) { Iterator<AgentTodoTask> it = m_todoTasks.iterator(); while (it.hasNext()) { AgentTodoTask task = it.next(); boolean flag = sendToRemoteAgent(task); if (flag) { // m_todoTasks.remove(task); it.remove(); m_doneTasks.add(task); } } // for (AgentTodoTask task : m_todoTasks) { // boolean flag = sendToRemoteAgent(task); // if (flag) { // m_todoTasks.remove(task); // m_doneTasks.add(task); // } // } } } public void setActive(boolean active) { this.active = active; } /** * 远端Agent重启,需要重新分配任务 */ protected void reset() { resetDo(); saveToFile(); } private void resetDo() { m_doneTasks.clear();// 清除所有已完成任务 m_todoTasks.clear();// 清除所有未完成任务 List<AgentTodoTask> tasks = getTodoTaskFromAgent(m_agent); log().info("全部工作是:" + tasks); m_todoTasks.addAll(tasks); } /** * 获得所有需要完成的任务 * * @param agent * @return */ private List<AgentTodoTask> getTodoTaskFromAgent(AgentComponent agent) { List<AgentTodoTask> tasks = new ArrayList<AgentTodoTask>(); List<AgentTaskNode> nodes = agent.getAllTaskNodes(); for (AgentTaskNode node : nodes) { AgentTodoTask task = node.convertToTask(); tasks.add(task); } return tasks; } /** * 添加任务 * * @param task */ public void addAgentTask(AgentTodoTask task) { addAgentTaskDo(task); saveToFile(); } private void addAgentTaskDo(AgentTodoTask task) { if (task.isDelete()) {// 如果是删除任务,先看该任务是否发出 AgentTodoType type = task.getType(); synchronized (m_todoTasks) { Iterator<AgentTodoTask> it = m_todoTasks.iterator(); while(it.hasNext()){ AgentTodoTask todoTask = it.next(); if (type == todoTask.getType() && task.getNodeid().equals(todoTask.getNodeid())) {// 找到了 it.remove(); return; } } // for (AgentTodoTask todoTask : m_todoTasks) { // if (type == todoTask.getType() // && task.getNodeid().equals(todoTask.getNodeid())) {// 找到了 // m_todoTasks.remove(todoTask); // return; // } // } } boolean flag = sendToRemoteAgent(task); if (flag) {// 发送成功 m_doneTasks.add(task); } else {// 没有发送成功 m_todoTasks.add(task); } } else { if (active) { boolean flag = sendToRemoteAgent(task); if (flag) { m_doneTasks.add(task); } else { m_todoTasks.add(task); } } else { m_todoTasks.add(task); } } log().info("已完成任务数:" + m_doneTasks.size()); log().info("未完成任务数:" + m_todoTasks.size()); } /** * 将任务发送到远程Agent上 * * @param task * @return */ private boolean sendToRemoteAgent(AgentTodoTask task) { Event event = task.convertToEvent(); boolean flag = EventSender.sendEvent(ipAddr, port, event); log().info( "向远程Agent : nodeid is " + event.getNodeid() + ",uei is " + event.getUei() + "发送事件,发送 :" + flag); log().info( "向远程Agent : ipaddr is " + ipAddr + ",port is " + port + "发送事件,发送 :" + flag); return flag; } ThreadCategory log() { return ThreadCategory.getInstance(getClass()); } public String getAgentAddress() { return ipAddr.getHostAddress(); } public int getAgentPort() { return port; } }