/* * 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) [2004, 2005, 2006], Hyperic, 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. */ package org.hyperic.hq.plugin.openldap; import org.hyperic.hq.product.MeasurementPlugin; import org.hyperic.hq.product.Metric; import org.hyperic.hq.product.MetricUnreachableException; import org.hyperic.hq.product.MetricInvalidException; import org.hyperic.hq.product.MetricNotFoundException; import org.hyperic.hq.product.MetricValue; import org.hyperic.hq.product.PluginException; import javax.naming.Context; import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; import javax.naming.directory.DirContext; import javax.naming.directory.InitialDirContext; import javax.naming.directory.SearchControls; import javax.naming.directory.SearchResult; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import java.util.Collection; import java.util.Hashtable; import java.util.Properties; import java.util.TreeSet; import javax.naming.CommunicationException; import org.apache.commons.logging.Log; import org.hyperic.hq.product.PluginManager; public class OpenLDAPMeasurementPlugin extends MeasurementPlugin { private DirContext ctx = null; private boolean hasMonitoringEnabled = false; private final Log log = getLog(); public DirContext getDirContext(Properties props) throws NamingException { if (this.ctx == null) { synchronized (this) { if (this.ctx == null) { log.debug("[getDirContext] creating new connection"); Collection rtn = new TreeSet(); Hashtable ldapEnv = new Hashtable(); String ldapDriver = props.getProperty("ldapDriver"), ldapHostURL = props.getProperty("ldapHostURL"), ldapAuthType = props.getProperty("ldapAuthType"), ldapPasswd = props.getProperty("ldapPasswd"), ldapTreePathToDN = props.getProperty("ldapTreePathToDN"); ldapTreePathToDN = (ldapTreePathToDN == null) ? "" : ldapTreePathToDN; ldapPasswd = (ldapPasswd == null) ? "" : ldapPasswd; ldapPasswd = (ldapPasswd.matches("^\\s*$")) ? "" : ldapPasswd; ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY, ldapDriver); ldapEnv.put(Context.PROVIDER_URL, ldapHostURL); ldapEnv.put(Context.SECURITY_AUTHENTICATION, ldapAuthType); ldapEnv.put(Context.SECURITY_PRINCIPAL, ldapTreePathToDN); ldapEnv.put(Context.SECURITY_CREDENTIALS, ldapPasswd); this.ctx = new InitialDirContext(ldapEnv); } } } return this.ctx; } @Override public MetricValue getValue(Metric metric) throws PluginException, MetricUnreachableException, MetricInvalidException, MetricNotFoundException { // will look like "generic:Type=GenericService,option1=option1,option2=option2" String objectName = metric.getObjectName(); // will look like "Availability" // -OR- // "cn=PDU,cn=Statistics,cn=Monitor:monitorCounter" String alias = metric.getAttributeName(); MetricValue res; if (metric.isAvail()) { try { hasMonitoringEnabled = hasMonitoringEnabled(metric); res = new MetricValue(Metric.AVAIL_UP, System.currentTimeMillis()); } catch (NamingException ex) { res = new MetricValue(Metric.AVAIL_DOWN, System.currentTimeMillis()); hasMonitoringEnabled = false; this.ctx = null; // reset connection [HHQ-4986] log.debug("[getValue] error:" + ex, ex); } } else { try { if (alias.equalsIgnoreCase("connectiontimems")) { res = getConnTimeMetric(metric); } else { if (hasMonitoringEnabled) { String[] attrs = alias.split(":"); if (attrs[0] == null || attrs[1] == null) { throw new MetricNotFoundException("bad template format"); } res = getMetric(metric, attrs[0], attrs[1]); } else { res = new MetricValue(MetricValue.NONE, System.currentTimeMillis()); } } } catch (CommunicationException ex) { log.debug("[getValue] error:" + ex, ex); this.ctx = null; // reset connection [HHQ-4986] throw new MetricNotFoundException(ex.getMessage(), ex); } catch (NamingException ex) { log.debug("[getValue] error:" + ex, ex); throw new MetricNotFoundException("Service " + objectName + ", " + alias + " not found", ex); } } return res; } private MetricValue getConnTimeMetric(Metric metric) throws NamingException { long start = System.currentTimeMillis(); hasMonitoringEnabled(metric); long now = System.currentTimeMillis(); return new MetricValue((now - start), now); } private MetricValue getMetric(Metric metric, String tree, String attr) throws MetricNotFoundException, NamingException { NamingEnumeration enumer = null; try { String[] a = {attr}; SearchControls cons = new SearchControls(); cons.setSearchScope(SearchControls.OBJECT_SCOPE); cons.setReturningAttributes(a); enumer = getDirContext(metric.getProperties()).search(tree, "(&(objectClass=*))", cons); while (enumer.hasMore()) { SearchResult searchresult = (SearchResult) enumer.next(); Attributes attrs = searchresult.getAttributes(); Attribute val; if (null != (val = attrs.get(attr))) { return new MetricValue(new Double(val.get().toString()), System.currentTimeMillis()); } } throw new MetricNotFoundException(""); } finally { if (enumer != null) { enumer.close(); } } } /** * @return true = monitoring is enabled * @return false = monitoring is not enabled * @exception NamingException no conection */ private boolean hasMonitoringEnabled(Metric metric) throws NamingException { NamingEnumeration enumer = null, enumerx = null, enumery = null; boolean res = false; try { String[] a = {"monitorContext"}; SearchControls cons = new SearchControls(); cons.setSearchScope(SearchControls.OBJECT_SCOPE); cons.setReturningAttributes(a); enumer = getDirContext(metric.getProperties()).search("", "(&(objectClass=*))", cons); while (enumer.hasMore() && !res) { SearchResult searchresult = (SearchResult) enumer.next(); Attributes attrs = searchresult.getAttributes(); enumerx = attrs.getIDs(); while (enumerx.hasMore()) { String id = (String) enumerx.next(); Attribute attr = attrs.get(id); res = true; } } } finally { if (enumer != null) { enumer.close(); } if (enumerx != null) { enumerx.close(); } if (enumery != null) { enumery.close(); } } log.debug("[hasMonitoringEnabled] res=" + res + " metric:" + metric); return res; } }