/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 2006-2011 The OpenNMS Group, Inc. * OpenNMS(R) is Copyright (C) 1999-2011 The OpenNMS Group, Inc. * * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc. * * OpenNMS(R) is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * OpenNMS(R) 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 OpenNMS(R). If not, see: * http://www.gnu.org/licenses/ * * For more information contact: * OpenNMS(R) Licensing <license@opennms.org> * http://www.opennms.org/ * http://www.opennms.com/ *******************************************************************************/ package org.opennms.netmgt.poller.pollables; import java.util.Collections; import java.util.Map; import java.util.TreeMap; import java.util.concurrent.ConcurrentSkipListMap; import org.opennms.core.utils.ThreadCategory; import org.opennms.netmgt.config.PollOutagesConfig; import org.opennms.netmgt.config.PollerConfig; import org.opennms.netmgt.config.poller.Downtime; import org.opennms.netmgt.config.poller.Package; import org.opennms.netmgt.config.poller.Parameter; import org.opennms.netmgt.config.poller.Service; import org.opennms.netmgt.model.PollStatus; import org.opennms.netmgt.poller.ServiceMonitor; import org.opennms.netmgt.scheduler.ScheduleInterval; import org.opennms.netmgt.scheduler.Timer; /** * Represents a PollableServiceConfig * * @author <a href="mailto:brozow@opennms.org">Mathew Brozowski</a> * @version $Id: $ */ public class PollableServiceConfig implements PollConfig, ScheduleInterval { private PollerConfig m_pollerConfig; private PollOutagesConfig m_pollOutagesConfig; private PollableService m_service; private Map<String,Object> m_parameters = null; private Package m_pkg; private Timer m_timer; private Service m_configService; private ServiceMonitor m_serviceMonitor; /** * <p>Constructor for PollableServiceConfig.</p> * * @param svc a {@link org.opennms.netmgt.poller.pollables.PollableService} object. * @param pollerConfig a {@link org.opennms.netmgt.config.PollerConfig} object. * @param pollOutagesConfig a {@link org.opennms.netmgt.config.PollOutagesConfig} object. * @param pkg a {@link org.opennms.netmgt.config.poller.Package} object. * @param timer a {@link org.opennms.netmgt.scheduler.Timer} object. */ public PollableServiceConfig(PollableService svc, PollerConfig pollerConfig, PollOutagesConfig pollOutagesConfig, Package pkg, Timer timer) { m_service = svc; m_pollerConfig = pollerConfig; m_pollOutagesConfig = pollOutagesConfig; m_pkg = pkg; m_timer = timer; m_configService = findService(pkg); ServiceMonitor monitor = getServiceMonitor(); monitor.initialize(m_service); } /** * @param pkg * @return */ private Service findService(Package pkg) { for (Service s : m_pkg.getServiceCollection()) { if (s.getName().equalsIgnoreCase(m_service.getSvcName())) { return s; } } throw new RuntimeException("Service name not part of package!"); } /** * <p>poll</p> * * @return a {@link org.opennms.netmgt.model.PollStatus} object. */ public PollStatus poll() { try { ServiceMonitor monitor = getServiceMonitor(); ThreadCategory.getInstance(getClass()).debug("Polling "+m_service+" using pkg "+m_pkg.getName()); PollStatus result = monitor.poll(m_service, getParameters()); ThreadCategory.getInstance(getClass()).debug("Finish polling "+m_service+" using pkg "+m_pkg.getName()+" result = "+result); return result; } catch (Throwable e) { ThreadCategory.getInstance(getClass()).error("Unexpected exception while polling "+m_service+". Marking service as DOWN", e); return PollStatus.down("Unexpected exception while polling "+m_service+". "+e); } } private ServiceMonitor getServiceMonitor() { if (m_serviceMonitor == null) { ServiceMonitor monitor = m_pollerConfig.getServiceMonitor(m_service.getSvcName()); m_serviceMonitor = new LatencyStoringServiceMonitorAdaptor(monitor, m_pollerConfig, m_pkg); } return m_serviceMonitor; } /** * Uses the existing package name to try and re-obtain the package from the poller config factory. * Should be called when the poller config has been reloaded. */ public synchronized void refresh() { Package newPkg = m_pollerConfig.getPackage(m_pkg.getName()); if (newPkg == null) { ThreadCategory.getInstance(PollableServiceConfig.class).warn("Package named "+m_pkg.getName()+" no longer exists."); } m_pkg = newPkg; m_configService = findService(m_pkg); m_parameters = null; } /** * Should be called when thresholds configuration has been reloaded */ public synchronized void refreshThresholds() { ((LatencyStoringServiceMonitorAdaptor)getServiceMonitor()).refreshThresholds(); } /** * @return */ private synchronized Map<String,Object> getParameters() { if (m_parameters == null) { m_parameters = createPropertyMap(m_configService); } return m_parameters; } private Map<String,Object> createPropertyMap(Service svc) { Map<String,Object> m = new ConcurrentSkipListMap<String,Object>(); for (Parameter p : svc.getParameterCollection()) { String val = p.getValue(); if (val == null) { val = (p.getAnyObject() == null ? "" : p.getAnyObject().toString()); } m.put(p.getKey(), val); } return m; } /** * <p>getCurrentTime</p> * * @return a long. */ public long getCurrentTime() { return m_timer.getCurrentTime(); } /** * <p>getInterval</p> * * @return a long. */ public long getInterval() { if (m_service.isDeleted()) return -1; long when = m_configService.getInterval(); if (m_service.getStatus().isDown()) { long downSince = m_timer.getCurrentTime() - m_service.getStatusChangeTime(); boolean matched = false; for (Downtime dt : m_pkg.getDowntimeCollection()) { if (dt.getBegin() <= downSince) { if (dt.getDelete() != null && (dt.getDelete().equals("yes") || dt.getDelete().equals("true"))) { when = -1; matched = true; } else if (dt.hasEnd() && dt.getEnd() > downSince) { // in this interval // when = dt.getInterval(); matched = true; } else // no end { when = dt.getInterval(); matched = true; } } } if (!matched) { ThreadCategory.getInstance(getClass()).warn("getInterval: Could not locate downtime model, throwing runtime exception"); throw new RuntimeException("Downtime model is invalid, cannot schedule service " + m_service); } } if (when < 0) { m_service.sendDeleteEvent(); } return when; } /** * <p>scheduledSuspension</p> * * @return a boolean. */ public boolean scheduledSuspension() { long nodeId=m_service.getNodeId(); for (String outageName : m_pkg.getOutageCalendarCollection()) { // Does the outage apply to the current time? if (m_pollOutagesConfig.isTimeInOutage(m_timer.getCurrentTime(), outageName)) { // Does the outage apply to this interface? if (m_pollOutagesConfig.isNodeIdInOutage(nodeId, outageName) || (m_pollOutagesConfig.isInterfaceInOutage(m_service.getIpAddr(), outageName)) || (m_pollOutagesConfig.isInterfaceInOutage("match-any", outageName))) { if (ThreadCategory.getInstance(getClass()).isDebugEnabled()) ThreadCategory.getInstance(getClass()).debug("scheduledOutage: configured outage '" + outageName + "' applies, " + m_configService + " will not be polled."); return true; } } } //return outageFound; return false; } }