/** * NOTE: This copyright does *not* cover user programs that use HQ * program services by normal system calls through the application * program interfaces provided as part of the Hyperic Plug-in Development * Kit or the Hyperic Client Development Kit - this is merely considered * normal use of the program, and does *not* fall under the heading of * "derived work". * * Copyright (C) [2009-2010], VMware, Inc. * This file is part of HQ. * * HQ is free software; you can redistribute it and/or modify * it under the terms version 2 of the GNU General Public License as * published by the Free Software Foundation. This program is distributed * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. * */ /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.hyperic.hq.plugin.sybase; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.HashMap; import java.util.Properties; import org.hyperic.hq.product.Collector; import org.hyperic.hq.product.JDBCMeasurementPlugin; import org.hyperic.hq.product.Metric; import org.hyperic.hq.product.MetricNotFoundException; import org.hyperic.hq.product.MetricUnreachableException; import org.hyperic.hq.product.MetricValue; import org.hyperic.hq.product.PluginException; import org.hyperic.hq.product.SigarMeasurementPlugin; import org.hyperic.util.config.ConfigResponse; import org.hyperic.util.jdbc.DBUtil; /** * * @author laullon */ public class EngineMeasurementPlugin extends SigarMeasurementPlugin { private static final HashMap connectionCache = new HashMap(); private static final HashMap pidsCache = new HashMap(); private static final String SIGAR_DOMAIN = "sybase.engine.sigar"; public MetricValue getValue(Metric metric) throws PluginException, MetricNotFoundException, MetricUnreachableException { MetricValue res; getLog().debug("[getValue] metric=" + metric); if (metric.getDomainName().equals(SIGAR_DOMAIN)) { res = getSigarValue(metric); } else if (metric.getAttributeName().equals(Metric.ATTR_AVAIL)) { res = getAvailability(metric); } else if (metric.getAttributeName().startsWith("EngineUtilization")) { res = Collector.getValue(this, metric); } else { throw new MetricNotFoundException(metric.getAttributeName()); } return res; } private MetricValue getAvailability(Metric metric) throws MetricNotFoundException { Statement stmt = null; ResultSet rs = null; Properties props = metric.getProperties(); String eId = metric.getObjectProperties().getProperty("id"); double res = Metric.AVAIL_DOWN; Connection conn = null; String url = props.getProperty(JDBCMeasurementPlugin.PROP_URL, ""); String user = props.getProperty(JDBCMeasurementPlugin.PROP_USER, ""); String pass = props.getProperty(JDBCMeasurementPlugin.PROP_PASSWORD, ""); try { conn = getCachedConnection(url, user, pass); stmt = conn.createStatement(); rs = stmt.executeQuery("select status from sysengines where engine=" + eId); if (rs.next()) { String status = rs.getString("status").trim(); getLog().debug("[getAvailability] egine '" + eId + "' status='" + status + "'"); if (status.equalsIgnoreCase("online")) { res = Metric.AVAIL_UP; } else { res = Metric.AVAIL_WARN; } } else { getLog().debug("[getAvailability] egine '" + eId + "' status not found"); } } catch (SQLException e) { getLog().error("Error getting engine '" + eId + "' pid -> " + e.getMessage()); DBUtil.closeJDBCObjects(getLog(), conn, null, null); removeCachedConnection(url, user, pass); conn=null; } finally { if (conn != null) { DBUtil.closeJDBCObjects(getLog(), null, stmt, rs); } } return new MetricValue(res); } public MetricValue getSigarValue(Metric metric) throws PluginException, MetricNotFoundException, MetricUnreachableException { MetricValue res = null; String eId = metric.getProperties().getProperty("id"); String ePid = (String) pidsCache.get(eId); if (ePid == null) { ePid = getEnginePID(metric.getProperties()); pidsCache.put(eId, ePid); getLog().debug("Engine '" + eId + "' pid='" + ePid + "'"); } if (ePid == null) { throw new MetricNotFoundException("engine '" + eId + "' pid not found"); } metric.setObjectName(metric.getObjectName().replace("%process.query%", ePid)); try { res = super.getValue(metric); } catch (PluginException ex) { pidsCache.remove(eId); throw ex; } catch (MetricNotFoundException ex) { pidsCache.remove(eId); throw ex; } catch (MetricUnreachableException ex) { pidsCache.remove(eId); throw ex; } return res; } private String getEnginePID(Properties props) { Statement stmt = null; ResultSet rs = null; String pid = null; String eId = props.getProperty("id"); try { String url = props.getProperty(JDBCMeasurementPlugin.PROP_URL, ""), user = props.getProperty(JDBCMeasurementPlugin.PROP_USER, ""), pass = props.getProperty(JDBCMeasurementPlugin.PROP_PASSWORD, ""); Connection conn = getCachedConnection(url, user, pass); stmt = conn.createStatement(); rs = stmt.executeQuery("select osprocid from sysengines where engine=" + eId); if (rs.next()) { pid = rs.getString("osprocid"); } } catch (SQLException e) { getLog().debug("Error getting engine '" + eId + "' pid"); } finally { DBUtil.closeJDBCObjects(getLog(), null, stmt, rs); } return pid; } protected Connection getCachedConnection(String url, String user, String pass) throws SQLException { String cacheKey = url + user + pass; Connection conn = null; synchronized (connectionCache) { conn = (Connection) connectionCache.get(cacheKey); if (conn == null) { conn = getConnection(url, user, pass); connectionCache.put(cacheKey, conn); } } return conn; } protected void removeCachedConnection(String url, String user, String pass) { String cacheKey = url + user + pass; synchronized (connectionCache) { connectionCache.remove(cacheKey); } } protected Connection getConnection(String url, String user, String password) throws SQLException { String pass = (password == null) ? "" : password; pass = (pass.matches("^\\s*$")) ? "" : pass; Properties props = new Properties(); props.put("CHARSET_CONVERTER_CLASS", "com.sybase.jdbc3.utils.TruncationConverter"); props.put("user", user); props.put("password", pass); return DriverManager.getConnection(url, props); } public String translate(String template, ConfigResponse config) { String rate = ""; if (template.contains(":sigar:") && template.contains("%process.query%")) { template = template.replace(":sigar:", ":" + SIGAR_DOMAIN + ":"); int ri = template.indexOf("__RATE__"); if (ri > 0) { rate = template.substring(ri); template = template.substring(0, ri); } template += ",id=" + config.getValue("id") + rate; } else if (template.contains(":EngineUtilization")) { // need to postfix attribute with engineid from configuration // because collector collects multiple values template = template.replace(":EngineUtilization", ":EngineUtilization" + config.getValue("id")); } return super.translate(template, config); } }