/src/server/xmlprovider/src/keymind/keywatch/bundles/provider/xmlrpc/ServiceHandler.java

http://keywatch.googlecode.com/ · Java · 315 lines · 172 code · 54 blank · 89 comment · 29 complexity · 644406c55655d3b6180ffaf901e689a9 MD5 · raw file

  1. /**
  2. * -----------------------------------------------------------------------------------------------
  3. * File: ServiceHandler.java
  4. *
  5. * Copyright (c) 2007 by Keymind Computing as.
  6. * All rights reserved.
  7. *
  8. * This file is subject to the terms and conditions of the Apache Licence 2.0.
  9. * See the file LICENCE in the main directory of the Keywatch distribution for more details.
  10. *
  11. * Revision History (use svn log or TortoiseSVN):
  12. * $URL: http://keywatch.googlecode.com/svn/trunk/src/server/xmlprovider/src/keymind/keywatch/bundles/provider/xmlrpc/ServiceHandler.java $
  13. * $Date: 2009-08-10 13:12:17 +0200 (Mon, 10 Aug 2009) $
  14. * -----------------------------------------------------------------------------------------------
  15. */
  16. package keymind.keywatch.bundles.provider.xmlrpc;
  17. import keymind.keywatch.common.Log;
  18. import keymind.keywatch.domainmodel.eventDomain.*;
  19. import keymind.keywatch.services.eventmanagement.IEventManagement;
  20. import keymind.keywatch.services.eventmanagement.ITaskManagement;
  21. import java.util.Hashtable;
  22. import java.util.Date;
  23. /**
  24. * Handle incoming requests from agents
  25. */
  26. public class ServiceHandler implements Constants
  27. {
  28. private Context ctx;
  29. private Activator xmlProvider;
  30. private IEventManagement eventManager;
  31. private ITaskManagement taskManager;
  32. private Hashtable monitors;
  33. /**
  34. * C'tor
  35. */
  36. public ServiceHandler()
  37. {
  38. ctx = KeyXmlRpcServer.getCtx();
  39. xmlProvider = KeyXmlRpcServer.getXmlProvider();
  40. taskManager = KeyXmlRpcServer.getTaskManager();
  41. eventManager = KeyXmlRpcServer.getEventManager();
  42. monitors = KeyXmlRpcServer.getMonitors();
  43. }
  44. /**
  45. * Called by Java agents upon startup.
  46. *
  47. * @param agentHostId Unique host identifier. This may be a host name or an IP address.
  48. * @param agentPort Port number of agent. If 0, PORT_AGENT_DEFAULT will be used.
  49. * @param urlSuffix Optional URL suffix, such as "RPC2" which would yield "http://ip:agentPort/RPC2"
  50. * @param props A potentially empty string of task properties for the agent. Example: "labels=xyx,abc;timeout=20"
  51. * @return A boolean holding the result from handleAgentRegistration
  52. */
  53. public synchronized boolean OnAgentStartedEx(String agentHostId, int agentPort, String urlSuffix, String props)
  54. {
  55. return handleAgentRegistration(agentHostId, agentPort, urlSuffix, props);
  56. }
  57. /**
  58. * Called by agent upon startup. This causes the agents and all its jobs to
  59. * be registered as tasks under the provider task.
  60. *
  61. * @param hostId Unique host identifier. This may be a host name or an IP address.
  62. * @return A boolean holding the result from handleAgentRegistration
  63. */
  64. public boolean OnAgentStarted(String hostId)
  65. {
  66. return handleAgentRegistration(hostId, DEFAULT_AGENT_PORT, XMLRPC_SUFFIX, "");
  67. }
  68. /**
  69. * Called just before the agent terminates itself
  70. *
  71. * @param hostId Unique host identifier. This may be a host name or an IP address.
  72. * @param reason Reason for termination
  73. * @return True
  74. */
  75. public boolean OnAgentTerminated(String hostId, String reason)
  76. {
  77. Event event = new Event();
  78. event.setCreated(new Date(System.currentTimeMillis()));
  79. event.setName("Agent down");
  80. event.setHost(hostId);
  81. event.setShortDescription("The agent at '" + hostId + "' has terminated itself.");
  82. event.setLongDescription(reason);
  83. Severity severity = new Severity();
  84. severity.setEnumerator(SEVERITY_FATAL);
  85. event.setSeverity(severity);
  86. event.setProvider(null);
  87. IEventManagement eventMgmt = KeyXmlRpcServer.getEventManager();
  88. eventMgmt.putEvent(KeyXmlRpcServer.getCtx(), event);
  89. // Update running flag. This will prevent the agent monitor from generating an
  90. // unnecessary 'agent down' event.
  91. Task task = KeyXmlRpcServer.getTaskManager().getTaskByName(
  92. KeyXmlRpcServer.getCtx(), PROVIDER_NAME + "/" + hostId);
  93. if(task != null)
  94. {
  95. task.setIsRunning(Boolean.FALSE);
  96. KeyXmlRpcServer.getTaskManager().putTask(KeyXmlRpcServer.getCtx(), task);
  97. }
  98. return true;
  99. }
  100. /**
  101. * Generic agent registration
  102. *
  103. * @param agentHostId Host id of agent
  104. * @param agentPort Port to use to talk to agent
  105. * @param urlSuffix Suffix to append to URL
  106. * @param propertyList List of properties
  107. * @return boolean status of registration
  108. */
  109. private boolean handleAgentRegistration(String agentHostId, int agentPort, String urlSuffix, String propertyList)
  110. {
  111. boolean res = false;
  112. try
  113. {
  114. Log.info(Constants.PROVIDER_AGENT_REGISTERING_PREFIX + agentHostId);
  115. // Get a fresh tree to work on
  116. Task rootTask = KeyXmlRpcServer.getXmlProvider().getRootTask(KeyXmlRpcServer.getCtx());
  117. rootTask = KeyXmlRpcServer.getTaskManager().getTaskByName(KeyXmlRpcServer.getCtx(),
  118. rootTask.getName());
  119. // The name of the agent task is '<providername>/<hostname>', since only using
  120. // the host name would cause conflicts when more than one type of agent runs
  121. // on the same host.
  122. String agentTaskName = rootTask.getName() + "/" + agentHostId;
  123. // This means that the host name, as provided by the agent, must be
  124. // 1) an ip address, or 2) a registered host name, either in a name server or
  125. // the local hosts file
  126. String url = "http://" + agentHostId + ":" + agentPort + "/";
  127. if (urlSuffix != null && urlSuffix.length() > 0)
  128. {
  129. url += urlSuffix;
  130. }
  131. Task agentTask = KeyXmlRpcServer.findByName(rootTask, agentTaskName);
  132. if (agentTask == null)
  133. {
  134. agentTask = new Task();
  135. agentTask.setParentTask(rootTask);
  136. agentTask.setName(agentTaskName);
  137. agentTask.setIsActive(true);
  138. agentTask.setUrl(url);
  139. agentTask.setHost(agentHostId);
  140. // Default monitor rate is 1 minute
  141. agentTask.setMonitorRate(Constants.MONITOR_RATE_DEFAULT_MIN);
  142. // Update list of childs by copying the existing list (if any) and appending the new task
  143. KeyXmlRpcServer.addSubTask(rootTask, agentTask);
  144. }
  145. else
  146. {
  147. agentTask.setHost(agentHostId);
  148. }
  149. // Add/update properties supplied by the agent
  150. if (propertyList != null && propertyList.length() > 0)
  151. {
  152. propertyList = propertyList.trim();
  153. String[] props = propertyList.split(";");
  154. for (int i = 0; i < props.length; i++)
  155. {
  156. String prop = props[i];
  157. String[] keyval = prop.split("=");
  158. if (keyval != null && keyval.length == 2)
  159. {
  160. Property newProp = new Property();
  161. newProp.setName(keyval[0].trim());
  162. newProp.setValue(keyval[1].trim());
  163. KeyXmlRpcServer.setTaskProperty(agentTask, newProp);
  164. }
  165. }
  166. }
  167. // The agent is obviously running...
  168. agentTask.setIsRunning(true);
  169. agentTask.setIsActive(true);
  170. // Get jobs
  171. KeyXmlRpcClient c = new KeyXmlRpcClient(url);
  172. Job[] jobs = c.GetJobStatusAll();
  173. if (jobs != null)
  174. {
  175. for (int i = 0; i < jobs.length; i++)
  176. {
  177. Task jobTask = KeyXmlRpcServer.findByName(agentTask, jobs[i].getSignature());
  178. if (jobTask == null)
  179. {
  180. jobTask = new Task();
  181. jobTask.setParentTask(agentTask);
  182. jobTask.setName(jobs[i].getSignature());
  183. jobTask.setHost(agentHostId);
  184. // Set host property and add subtask to agent
  185. KeyXmlRpcServer.addSubTask(agentTask, jobTask);
  186. }
  187. else
  188. {
  189. // Set host property
  190. jobTask.setHost(agentHostId);
  191. }
  192. jobTask.setUrl(url);
  193. jobTask.setIsActive(jobs[i].isActive());
  194. jobTask.setSchedule(jobs[i].getSchedule());
  195. // Assume daemon scripts are running initially... it is too early to ask for
  196. // actual running status since the agent is just starting up.
  197. jobTask.setIsRunning(jobs[i].isDaemon());
  198. // Add 'labels' property?
  199. if (jobs[i].labels != null && jobs[i].labels.length() > 0)
  200. {
  201. Property[] jobProps = jobTask.getProperties();
  202. Property match = null;
  203. for (int j = 0; jobProps != null && j < jobProps.length; j++)
  204. {
  205. if (jobProps[j].getName().equals(PROPERTY_KEY_LABELS))
  206. {
  207. match = jobProps[j];
  208. break;
  209. }
  210. }
  211. // This means we only set the 'labels' once; further updates the props
  212. // must occur on the server.
  213. Property jobProp = new Property();
  214. jobProp.setName(PROPERTY_KEY_LABELS);
  215. jobProp.setValue(jobs[i].labels);
  216. // Add or update property
  217. KeyXmlRpcServer.setTaskProperty(jobTask, jobProp);
  218. }
  219. }// foreach job
  220. KeyXmlRpcServer.softDeleteMissingJobs(agentTask, jobs);
  221. }
  222. // Update the tree and refresh the cached version
  223. KeyXmlRpcServer.getTaskManager().updateTaskTree(ctx, rootTask);
  224. xmlProvider.setRootTask(ctx, taskManager.getTaskByName(ctx, rootTask.getName()));
  225. // We registered correctly and that's what the agent needs to know (even if
  226. // the monitoring setup below fails)
  227. res = true;
  228. /* Start monitoring the agent */
  229. // Make sure we get an agent Task instance with proper id set (since this may well
  230. // be the first time the agent registers and thus a new instance has been created.)
  231. agentTask = taskManager.getTaskByName(ctx, agentTask.getName());
  232. // Remove old monitor to reset stuff
  233. Thread oldMonitor = (Thread)monitors.get(url);
  234. if (oldMonitor != null)
  235. {
  236. oldMonitor.interrupt();
  237. }
  238. Thread monitorThread = new Thread(
  239. new AgentMonitor(ctx, agentTask, taskManager, eventManager));
  240. monitors.put(url, monitorThread);
  241. // Start monitoring
  242. monitorThread.start();
  243. Log.info(Constants.PROVIDER_AGENT_REGISTERED_PREFIX + agentHostId);
  244. }
  245. catch (Exception e)
  246. {
  247. Log.error(e.toString());
  248. }
  249. return res;
  250. }
  251. /**
  252. * Get properties
  253. *
  254. * @param keypattern A key, which may be partial
  255. * @return a string of properties
  256. */
  257. public String[] GetProperties(String keypattern)
  258. {
  259. return new String[0];
  260. }
  261. }// ServiceHandler