/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 2007-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.capsd; import java.net.InetAddress; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.TreeMap; import org.exolab.castor.xml.ValidationException; import org.opennms.core.utils.InetAddressUtils; import org.opennms.core.utils.ThreadCategory; import org.opennms.netmgt.config.CapsdConfig; import org.opennms.netmgt.config.CapsdProtocolInfo; import org.opennms.netmgt.config.CapsdProtocolInfo.Action; import org.opennms.netmgt.config.capsd.Property; import org.opennms.netmgt.config.capsd.ProtocolConfiguration; import org.opennms.netmgt.config.capsd.ProtocolPlugin; import org.opennms.netmgt.config.capsd.Range; import org.springframework.beans.factory.InitializingBean; import org.springframework.util.Assert; /** * <p>PluginManager class.</p> * * @author ranger * @version $Id: $ */ public class PluginManager implements InitializingBean { private CapsdConfig m_capsdConfig; /** * The map of capsd plugins indexed by protocol. */ private Map<String, Plugin> m_pluginsByProtocol = new TreeMap<String, Plugin>(); /** * The map of capsd plugins indexed by implementing class. */ private Map<String, Plugin> m_pluginsByClass = new TreeMap<String, Plugin>(); /** * <p>Constructor for PluginManager.</p> */ public PluginManager() { super(); } /** * Now load the plugins! */ private void instantiatePlugins() throws ValidationException { List<ProtocolPlugin> plugins = getCapsdConfig().getProtocolPlugins(); for (ProtocolPlugin plugin : plugins) { try { if (m_pluginsByClass.containsKey(plugin.getClassName())) { Plugin oplugin = m_pluginsByClass.get(plugin.getClassName()); m_pluginsByProtocol.put(plugin.getProtocol(), oplugin); } else { Class<?> cplugin = Class.forName(plugin.getClassName()); Object oplugin = cplugin.newInstance(); if (!(oplugin instanceof Plugin)) { throw new ValidationException("CapsdConfigFactory: successfully loaded plugin class for protocol " + plugin.getProtocol() + ", class-name = " + plugin.getClassName() + ", however the class is not an instance of " + Plugin.class.getName()); } Plugin p = (Plugin) oplugin; // map them m_pluginsByClass.put(plugin.getClassName(), p); m_pluginsByProtocol.put(plugin.getProtocol(), p); } } catch (Throwable t) { String message = "CapsdConfigFactory: failed to load plugin for protocol " + plugin.getProtocol() + ", class-name = " + plugin.getClassName() + ", exception = " + t; log().error(message, t); throw new ValidationException(message, t); } } } private ThreadCategory log() { return ThreadCategory.getInstance(getClass()); } /** * Returns the list of protocol plugins and the associated actions for the * named address. The currently loaded configuration is used to find, build, * and return the protocol information. The returns information has all the * necessary element to check the address for capabilities. * * @param address * The address to get protocol information for. * @return The array of protocol information instances for the address. */ public CapsdProtocolInfo[] getProtocolSpecification(InetAddress address) { /* * The list of protocols that will be turned into * and array and returned to the caller. These are * of type ProtocolInfo */ List<CapsdProtocolInfo> lprotos = new ArrayList<CapsdProtocolInfo>(getCapsdConfig().getConfiguration().getProtocolPluginCount()); // go through all the defined plugins List<ProtocolPlugin> plugins = getCapsdConfig().getProtocolPlugins(); Iterator<ProtocolPlugin> pluginIter = plugins.iterator(); PLUGINLOOP: while (pluginIter.hasNext()) { ProtocolPlugin plugin = pluginIter.next(); boolean found = false; /* * Loop through the specific and ranges to find out * if there is a particular protocol specification */ for (ProtocolConfiguration pluginConf : getCapsdConfig().getProtocolConfigurations(plugin)) { // Check specifics first List<String> saddrs = getCapsdConfig().getSpecifics(pluginConf); Iterator<String> saddrIter = saddrs.iterator(); while (saddrIter.hasNext() && !found) { String saddr = saddrIter.next(); InetAddress taddr = InetAddressUtils.addr(saddr); if (taddr != null && taddr.equals(address)) { found = true; } } // check the ranges List<Range> ranges = getCapsdConfig().getRanges(pluginConf); Iterator<Range> rangeIter = ranges.iterator(); while (rangeIter.hasNext() && !found) { Range rng = rangeIter.next(); InetAddress start = null; start = InetAddressUtils.addr(rng.getBegin()); if (start == null) { log().warn("CapsdConfigFactory: failed to convert address " + rng.getBegin() + " to InetAddress"); continue; } InetAddress stop = null; stop = InetAddressUtils.addr(rng.getEnd()); if (stop == null) { log().warn("CapsdConfigFactory: failed to convert address " + rng.getEnd() + " to InetAddress"); continue; } if (InetAddressUtils.isInetAddressInRange(address.getAddress(), start.getAddress(), stop.getAddress())) { found = true; } } /* * if it has not be found yet then it's not * in this particular plugin conf, check the * next */ if (!found) { continue; } /* * if found then build protocol * specification if on, else next protocol. */ String scan = null; if ((scan = pluginConf.getScan()) != null) { if (scan.equals("enable")) { lprotos.add(new CapsdProtocolInfo(plugin.getProtocol(), m_pluginsByProtocol.get(plugin.getProtocol()), null, Action.AUTO_SET)); continue PLUGINLOOP; } else if (scan.equals("off")) { continue PLUGINLOOP; } } else if ((scan = plugin.getScan()) != null) { if (scan.equals("off")) { continue PLUGINLOOP; } } // it's either on specifically, or by default // so map it parameters Map<String, Object> params = new TreeMap<String, Object>(); // add the plugin defaults first, then specifics addProperties(getCapsdConfig().getPluginProperties(plugin), params); addProperties(getCapsdConfig().getProtocolConfigurationProperties(pluginConf), params); lprotos.add(new CapsdProtocolInfo(plugin.getProtocol(), m_pluginsByProtocol.get(plugin.getProtocol()), params, Action.SCAN)); } // end ProtocolConfiguration loop // use default config if not found if (!found) { // if found then build protocol // specification if on, else next protocol. if ("off".equals(plugin.getScan())) { continue PLUGINLOOP; } // it's either on specifically, or by default // so map it parameters Map<String, Object> params = new TreeMap<String, Object>(); addProperties(getCapsdConfig().getPluginProperties(plugin), params); lprotos.add(new CapsdProtocolInfo(plugin.getProtocol(), m_pluginsByProtocol.get(plugin.getProtocol()), params, Action.SCAN)); } } // end ProtocolPlugin /* * copy the protocol information to * the approriate array and return that * result */ CapsdProtocolInfo[] result = new CapsdProtocolInfo[lprotos.size()]; return lprotos.toArray(result); } private static void addProperties(List<Property> properties, Map<String, Object> params) { for (Property property : properties) { params.put(property.getKey(), property.getValue()); } } /** * <p>getCapsdConfig</p> * * @return a {@link org.opennms.netmgt.config.CapsdConfig} object. */ public CapsdConfig getCapsdConfig() { return m_capsdConfig; } /** * <p>setCapsdConfig</p> * * @param capsdConfig a {@link org.opennms.netmgt.config.CapsdConfig} object. */ public void setCapsdConfig(CapsdConfig capsdConfig) { m_capsdConfig = capsdConfig; } /** * <p>afterPropertiesSet</p> * * @throws org.exolab.castor.xml.ValidationException if any. */ @Override public void afterPropertiesSet() throws ValidationException { Assert.state(m_capsdConfig != null, "property capsdConfig must be set to a non-null value"); instantiatePlugins(); } }