package eu.choreos.monitoring.platform.utils; import java.io.IOException; import java.io.InputStream; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import eu.choreos.monitoring.platform.daemon.datatypes.Host; import eu.choreos.monitoring.platform.daemon.datatypes.Metric; import eu.choreos.monitoring.platform.exception.GangliaException; public class GmondDataReader { private String host; private int port; private List<Host> lastKnownHosts; private Socket socket; public GmondDataReader(String host, int port) { this.host = host; this.port = port; lastKnownHosts = new ArrayList<Host>(); } public List<Host> getUpToDateHostsInfo() throws GangliaException { return parseGangliaMetrics(getGangliaCurrentMetrics()); } private List<Host> parseGangliaMetrics(Document gangliaXML) { lastKnownHosts.clear(); gangliaXML.getDocumentElement().normalize(); NodeList clusterNodeList = gangliaXML.getElementsByTagName("CLUSTER"); for (int i = 0; i < clusterNodeList.getLength(); i++) { Element newClusterNode = (Element) clusterNodeList.item(i); String timestamp = newClusterNode.getAttribute("LOCALTIME"); NodeList newHostNodeList = newClusterNode.getElementsByTagName("HOST"); String clusterName = newClusterNode.getAttribute("NAME"); for (int j = 0; j < newHostNodeList.getLength(); j++) { Element element = (Element) newHostNodeList.item(j); Host host = createHostFromElement(element, clusterName); long ts; try{ ts = Long.parseLong(timestamp); } catch (NumberFormatException e) { ts = System.currentTimeMillis(); } host.setLastMeasurementTimestamp(ts); lastKnownHosts.add(host); } } return lastKnownHosts; } private Document getGangliaCurrentMetrics() throws GangliaException { try { if (socket == null) createSocket(); else if (socket.isClosed()) createSocket(); } catch (UnknownHostException e) { throw new GangliaException(GangliaException.CONNECTION_ERROR_UNKNOWN_HOST); } catch (IOException e) { throw new GangliaException( GangliaException.CONNECTION_ERROR_COULD_NOT_READ_FROM_SOCKET); } Document dom = getGangliaMetricsFromSocket(socket); closeSocket(socket); return dom; } private Document getGangliaMetricsFromSocket(Socket socket) throws GangliaException { InputStream in = getStreamFromSocket(socket); Document dom = convertToDomDocument(in); closeInputStream(in); return dom; } private void closeSocket(Socket socket) throws GangliaException { if (socket != null) { try { socket.close(); } catch (IOException ex) { throw new GangliaException( GangliaException.CONNECTION_ERROR_COULD_NOT_CLOSE_SOCKET); } } } private Document convertToDomDocument(InputStream in) throws GangliaException { Document dom = null; try { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db; db = dbf.newDocumentBuilder(); dom = db.parse(in); } catch (ParserConfigurationException e) { throw new GangliaException( GangliaException.CONNECTION_ERROR_COULD_NOT_PARSE_METRICS_INPUT); } catch (SAXException e) { throw new GangliaException( GangliaException.CONNECTION_ERROR_COULD_NOT_PARSE_METRICS_INPUT); } catch (IOException e) { throw new GangliaException( GangliaException.CONNECTION_ERROR_COULD_NOT_READ_FROM_SOCKET); } return dom; } private void closeInputStream(InputStream in) throws GangliaException { if (in != null) { try { in.close(); } catch (IOException e1) { throw new GangliaException( GangliaException.CONNECTION_ERROR_COULD_NOT_CLOSE_SOCKET); } } } private InputStream getStreamFromSocket(Socket socket) throws GangliaException { InputStream in = null; try { in = socket.getInputStream(); } catch (IOException e) { throw new GangliaException( GangliaException.CONNECTION_ERROR_COULD_NOT_READ_FROM_SOCKET); } return in; } private void createSocket() throws UnknownHostException, IOException { socket = new Socket(InetAddress.getByName(host), port); } public void setSocket(Socket socket) { this.socket = socket; } private Host createHostFromElement(Element hostNode, String clusterName) { HashMap<String, Metric> metrics = new HashMap<String, Metric>(); String hostName = hostNode.getAttributeNode("NAME").getNodeValue(); String ip = hostNode.getAttributeNode("IP").getNodeValue(); int tn = Integer.parseInt(hostNode.getAttributeNode("TN").getNodeValue()); int tmax = Integer.parseInt(hostNode.getAttributeNode("TMAX").getNodeValue()); NodeList metricNodeList = hostNode.getElementsByTagName("METRIC"); for (int i = 0; i < metricNodeList.getLength(); i++) { Element el = (Element) metricNodeList.item(i); metrics.put(el.getAttributeNode("NAME").getNodeValue(), new Metric(el.getAttributeNode("NAME").getNodeValue(), el.getAttributeNode("VAL").getNodeValue(), Integer.parseInt(el.getAttributeNode("TN").getNodeValue()), Integer.parseInt(el.getAttributeNode("TMAX").getNodeValue()), Integer.parseInt(el.getAttributeNode("DMAX").getNodeValue()))); } Host host = new Host(clusterName, hostName, ip, metrics, tn, tmax); return host; } }