GroupNode findOrCreateSystemNode(MonitorEngine engine) { ManagedNode infNode = nodeService.findByPath(ManagedNode.INFRASTRUCTURE_PATH); // 兼容手工创建时,引擎资源节点存在对应管理节点的情况 // 创建 引擎系统 群组,其中存放监控服务器,监控引擎,相关redis/mysql/nginx等自带应用 GroupNode engineSystemGroupNode; try { engineSystemGroupNode = (GroupNode) nodeService.findByPath(engine.getSystemPath()); } catch (IllegalArgumentException e) { // Not found exception engineSystemGroupNode = new GroupNode(); engineSystemGroupNode.cascadeCreating(); engineSystemGroupNode.setPath(engine.getSystemPath()); if (engine.isDefault()) { engineSystemGroupNode.setLabel("缺省监控系统"); } else { engineSystemGroupNode.setLabel(engine.getLabel() + "系统"); } engineSystemGroupNode.setIcon("monitor_system"); engineSystemGroupNode.setComment("Auto created system group node for " + engine.getLabel()); try { nodeService.create(infNode, engineSystemGroupNode); } catch (NodeException ex) { throw new ApplicationContextException("Can't auto create engine group node", ex); } } return engineSystemGroupNode; }
private MonitorEngine initDefaultEngine() { MonitorEngine engine = new MonitorEngine(); engine.setName("default"); engine.setLabel("缺省引擎"); engine.setAddress("0.0.0.0:1000"); return engine; }
@Override public MonitorEngine approve(MonitorEngine engine, String name, String label) throws ResourceException { engine.setName(name); engine.setLabel(label); approveIt(engine); return update(engine); }
@Override protected void validateOnCreate(MonitorEngine engine) throws ValidationException { super.validateOnCreate(engine); MonitorEngine exist = findByAddress(engine.getAddress()); if (exist != null) { throw new ValidationException("There is an engine with address " + engine.getAddress()); } }
protected boolean isDefault(MonitorEngine engine) { // 判断引擎的名称,这个是由管理员自行设置的 if (engine.isDefault()) return true; // 在某些本机场景下, server address = localhost, engine address = 192.168.12.63 SocketAddress serverAddr = IpUtils.parseSocketAddress(serverService.getServer().getAddress()); SocketAddress engineAddr = IpUtils.parseSocketAddress(engine.getAddress()); return StringUtils.equals(serverAddr.getHost(), engineAddr.getHost()); }
/** * * * <h2>根据默认规则执行对该引擎的批准动作</h2> * * @param engine 刚刚注册上来的监控引擎 */ void performApproval(MonitorEngine engine) { if (isDefault(engine)) { engine.setLabel("缺省引擎"); engine.setName("default"); approveIt(engine); } else if (isAutoApprove(engine)) { // 这种情况,应该在用户手工创建时,engine system node 和engine scope node都已经创建 approveIt(engine); } }
@Override protected void onApprove(MonitorEngine engine, MonitorEngine... oldEngines) { if (oldEngines.length == 0) return; MonitorEngine oldEngine = oldEngines[0]; String legacySystemPath = oldEngine.getSystemPath(); String systemPath = engine.getSystemPath(); autoUpdateNodesForEngine(legacySystemPath, systemPath); String legacyScopePath = oldEngine.getScopePath(); String scopePath = engine.getScopePath(); autoUpdateNodesForEngine(legacyScopePath, scopePath); }
@Override protected void validateOnUpdate(MonitorEngine exist, MonitorEngine resource) throws ValidationException { super.validateOnUpdate(exist, resource); // IP地址变了 if (!StringUtils.equals(exist.getAddress(), resource.getAddress())) { MonitorEngine another = findByAddress(resource.getAddress()); if (another != null) { throw new ValidationException( "There is another engine with address " + resource.getAddress()); } } }
void createEngineNode(MonitorEngine engine, GroupNode engineSystemGroupNode) { // 在引擎系统中,添加引擎自身这个节点 String enginePath = engine.getSystemPath() + "/engine"; ResourceNode engineNode; try { nodeService.findByPath(enginePath); } catch (Exception e) { engineNode = new ResourceNode(); // 说明该节点是在创建引擎后被级联自动创建的 engineNode.cascadeCreating(); engineNode.setResource(engine); engineNode.setPath(enginePath); engineNode.setLabel(engine.getLabel()); engineNode.setIcon("monitor_engine"); engineNode.setState(State.Running); engineNode.setComment("Auto created engine node for " + engine.getLabel()); try { nodeService.create(engineSystemGroupNode, engineNode); } catch (NodeException ex) { throw new ApplicationContextException("Can't auto create engine node", ex); } } }
void cleanupEngineHost(MonitorEngine engine) throws ResourceException { Host host = engine.getHost(); // TODO 如果是默认引擎所在的主机,其还与监控服务器,以及其他应用存在RunAt关系这些关系还没清除掉 // 最终逻辑,应该是监控引擎删除/尝试删除所依赖的组件(存在server的情况下删除不掉) // 而后删除 引擎 + 主机的 RunAt关系 // 尝试删除主机(但是由于未能将server, mysql, redis等组件删除,所以主机存在关系,无法删除) if (host != null) { LinkService linkService = serviceLocator.locateLinkService(LinkType.RunOn.name()); if (linkService == null) throw new IllegalStateException( "Can't find link service for link type = " + LinkType.RunOn); linkService.unlink(engine, host, LinkType.RunOn); //noinspection unchecked HostService<Host> hostService = (HostService<Host>) serviceLocator.locate(host.getType()); try { hostService.delete(host); } catch (ResourceException e) { logger.warn("Can't delete the engine host, because of there are some legacy links ", e); } } }
@Override public MonitorEngine register(MonitorEngine engine) throws ResourceException { // 先执行自动批准动作 performApproval(engine); // 如果是从监控服务器下载下来的引擎,关联了相应的engine id,则直接更新 if (StringUtils.isNotBlank(engine.getEngineId())) { MonitorEngine legacy = findByEngineId(engine.getEngineId()); // id/name/label 保留数据库中的值 engine.setId(legacy.getId()); engine.setName(legacy.getName()); engine.setLabel(legacy.getLabel()); // properties 合并 if (legacy.getProperties() != null) { if (engine.getProperties() == null) { engine.setProperties(legacy.getProperties()); } else { engine.getProperties().putAll(legacy.getProperties()); } } return update(legacy, engine); } else if (isDefault(engine)) { // 还有一种常见情况,就是缺省引擎(与监控服务器安装在同一个地址),而后没有配置engineId MonitorEngine defaultEngine = getRepository().findDefaultEngine(); engine.setEngineId(defaultEngine.getEngineId()); return update(defaultEngine, engine); } else { // 否则创建一个新的实例 return create(engine); } }
void approveIt(MonitorEngine engine) { engine.setApproveStatus(ApproveStatus.Approved); engine.setApiToken(UUID.randomUUID().toString()); }
@Override public MonitorEngine reject(MonitorEngine engine) throws ResourceException { engine.setApproveStatus(ApproveStatus.Rejected); engine.setApiToken(null); // 防止提交进来 return update(engine); }
/** * 判断某个引擎是否需要自动批准 * * @param engine 被判断的引擎 * @return 是否需要自动批准 */ protected boolean isAutoApprove(MonitorEngine engine) { // 增加一个自动批准的机制,便于集成测试 return engine.getProperty("autoApproveForIntegration", "false").equals("true"); }
/** * * * <h2>实际执行添加引擎的动作</h2> * * <p>有如下添加方式(对应两种情况): * * <ol> * <li>管理员通过界面主动新建一个监控引擎(而后由脚本安装) 用户输入了如下信息 * <ul> * <li>引擎路径(安装目标路径) * <li>引擎地址(也是主机地址) * <li>主机类型 * <li>主机登录信息 * </ul> * 程序在本步骤保持新的引擎对象以及其所在主机信息之后,后继应该使用该主机信息,将引擎安装到相应目录去 * <li>用户在特定机器上安装引擎(而后引擎启动时,通过监控服务器SPI自动注册) * <ul> * <li>引擎路径(安装目标路径) * <li>引擎地址(也是主机地址) * <li>进程pids * <li>主机类型 * </ul> * </ol> * * 开发者可以通过监控引擎是否有pids值判断是否是界面输入的监控引擎 * * @param engine 新注册的引擎对象 * @throws ResourceException */ @Override protected void performCreate(MonitorEngine engine) throws ResourceException { boolean manual; manual = engine.getPids() == null || engine.getPids().isEmpty(); // 新建的引擎,没有真的引擎实例与之关联,所以,必定 不可用, 待批准 engine.setEngineId(UUID.randomUUID().toString()); engine.setAvailability(Availability.Unavailable); engine.setConfigStatus(ConfigStatus.Unknown); engine.setPerformance(Performance.Unknown); engine.setApproveStatus(ApproveStatus.Requested); // 没有预先创建,自动注册的监控引擎没有name,需要为其生成 // @see dnt.monitor.engine.support.IdentityManager#createLocalEngine(String) if (StringUtils.isBlank(engine.getName())) { int maxPending = getRepository().countMaxPending(); maxPending++; engine.setLabel("新监控引擎#" + maxPending); String name = "pending_" + maxPending; engine.setName(name); engine.setApiToken(null); // 防止提交进来 } // 本函数中没有包括创建该引擎所在主机,这个动作是在引擎创建后, // 由 SetupEngineAfterCreation这个handler完成 logger.debug( "An engine from {} created in {} mode", engine.getAddress(), (manual ? "manual" : "auto")); super.performCreate(engine); }