/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 2009-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.provision.persist; import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; import java.util.Map.Entry; import org.apache.commons.beanutils.MethodUtils; import org.opennms.core.soa.ServiceRegistry; import org.opennms.core.utils.BeanUtils; import org.opennms.core.utils.PropertyPath; import org.opennms.core.utils.ThreadCategory; import org.opennms.netmgt.provision.OnmsPolicy; import org.opennms.netmgt.provision.ServiceDetector; import org.opennms.netmgt.provision.annotations.Policy; import org.opennms.netmgt.provision.persist.foreignsource.ForeignSource; import org.opennms.netmgt.provision.persist.foreignsource.PluginConfig; import org.opennms.netmgt.provision.support.PluginWrapper; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; /** * <p>DefaultForeignSourceService class.</p> * * @author ranger * @version $Id: $ */ public class DefaultForeignSourceService implements ForeignSourceService, InitializingBean { @Autowired private ServiceRegistry m_serviceRegistry; @Autowired @Qualifier("deployed") private ForeignSourceRepository m_deployedForeignSourceRepository; @Autowired @Qualifier("pending") private ForeignSourceRepository m_pendingForeignSourceRepository; private static Map<String,String> m_detectors; private static Map<String,String> m_policies; private static Map<String, PluginWrapper> m_wrappers; @Override public void afterPropertiesSet() throws Exception { BeanUtils.assertAutowiring(this); } /** {@inheritDoc} */ public void setDeployedForeignSourceRepository(ForeignSourceRepository repo) { m_deployedForeignSourceRepository = repo; } /** {@inheritDoc} */ public void setPendingForeignSourceRepository(ForeignSourceRepository repo) { m_pendingForeignSourceRepository = repo; } /** * <p>getAllForeignSources</p> * * @return a {@link java.util.Set} object. */ public Set<ForeignSource> getAllForeignSources() { Set<ForeignSource> foreignSources = new TreeSet<ForeignSource>(); foreignSources.addAll(m_pendingForeignSourceRepository.getForeignSources()); for (ForeignSource fs : m_deployedForeignSourceRepository.getForeignSources()) { if (!foreignSources.contains(fs)) { foreignSources.add(fs); } } return foreignSources; } /** {@inheritDoc} */ public ForeignSource getForeignSource(String name) { ForeignSource fs = m_pendingForeignSourceRepository.getForeignSource(name); if (fs.isDefault()) { return m_deployedForeignSourceRepository.getForeignSource(name); } return fs; } /** {@inheritDoc} */ public ForeignSource saveForeignSource(String name, ForeignSource fs) { normalizePluginConfigs(fs); m_pendingForeignSourceRepository.save(fs); return fs; } /** {@inheritDoc} */ public void deleteForeignSource(String name) { if (name.equals("default")) { m_pendingForeignSourceRepository.resetDefaultForeignSource(); m_deployedForeignSourceRepository.resetDefaultForeignSource(); } else { ForeignSource fs = getForeignSource(name); m_pendingForeignSourceRepository.delete(fs); m_deployedForeignSourceRepository.delete(fs); } } /** {@inheritDoc} */ public ForeignSource cloneForeignSource(String name, String target) { ForeignSource fs = getForeignSource(name); fs.setDefault(false); fs.setName(target); m_deployedForeignSourceRepository.save(fs); m_pendingForeignSourceRepository.delete(fs); return m_deployedForeignSourceRepository.getForeignSource(target); } /** {@inheritDoc} */ public ForeignSource addParameter(String foreignSourceName, String pathToAdd) { ForeignSource fs = getForeignSource(foreignSourceName); PropertyPath path = new PropertyPath(pathToAdd); Object obj = path.getValue(fs); try { MethodUtils.invokeMethod(obj, "addParameter", new Object[] { "key", "value" }); } catch (NoSuchMethodException e) { throw new IllegalArgumentException("Unable to call addParameter on object of type " + obj.getClass(), e); } catch (IllegalAccessException e) { throw new IllegalArgumentException("unable to access property "+pathToAdd, e); } catch (InvocationTargetException e) { throw new IllegalArgumentException("an execption occurred adding a parameter to "+pathToAdd, e); } m_pendingForeignSourceRepository.save(fs); return fs; } /** {@inheritDoc} */ public ForeignSource deletePath(String foreignSourceName, String pathToDelete) { ForeignSource fs = getForeignSource(foreignSourceName); PropertyPath path = new PropertyPath(pathToDelete); Object objToDelete = path.getValue(fs); Object parentObject = path.getParent() == null ? fs : path.getParent().getValue(fs); String propName = path.getPropertyName(); String methodSuffix = Character.toUpperCase(propName.charAt(0))+propName.substring(1); String methodName = "delete"+methodSuffix; try { MethodUtils.invokeMethod(parentObject, methodName, new Object[] { objToDelete }); } catch (NoSuchMethodException e) { throw new IllegalArgumentException("Unable to find method "+methodName+" on object of type "+parentObject.getClass()+" with argument " + objToDelete, e); } catch (IllegalAccessException e) { throw new IllegalArgumentException("unable to access property "+pathToDelete, e); } catch (InvocationTargetException e) { throw new IllegalArgumentException("an execption occurred deleting "+pathToDelete, e); } m_pendingForeignSourceRepository.save(fs); return fs; } /** {@inheritDoc} */ public ForeignSource addDetectorToForeignSource(String foreignSource, String name) { ForeignSource fs = getForeignSource(foreignSource); PluginConfig pc = new PluginConfig(name, "unknown"); fs.addDetector(pc); m_pendingForeignSourceRepository.save(fs); return fs; } /** {@inheritDoc} */ public ForeignSource deleteDetector(String foreignSource, String name) { ForeignSource fs = getForeignSource(foreignSource); List<PluginConfig> detectors = fs.getDetectors(); for (Iterator<PluginConfig> i = detectors.iterator(); i.hasNext(); ) { PluginConfig pc = i.next(); if (pc.getName().equals(name)) { i.remove(); break; } } m_pendingForeignSourceRepository.save(fs); return fs; } /** {@inheritDoc} */ public ForeignSource addPolicyToForeignSource(String foreignSource, String name) { ForeignSource fs = getForeignSource(foreignSource); PluginConfig pc = new PluginConfig(name, "unknown"); fs.addPolicy(pc); m_pendingForeignSourceRepository.save(fs); return fs; } /** {@inheritDoc} */ public ForeignSource deletePolicy(String foreignSource, String name) { ForeignSource fs = getForeignSource(foreignSource); List<PluginConfig> policies = fs.getPolicies(); for (Iterator<PluginConfig> i = policies.iterator(); i.hasNext(); ) { PluginConfig pc = i.next(); if (pc.getName().equals(name)) { i.remove(); break; } } m_pendingForeignSourceRepository.save(fs); return fs; } /** * <p>getDetectorTypes</p> * * @return a {@link java.util.Map} object. */ public Map<String, String> getDetectorTypes() { if (m_detectors == null) { Map<String,String> detectors = new TreeMap<String,String>(); for (ServiceDetector d : m_serviceRegistry.findProviders(ServiceDetector.class)) { String serviceName = d.getServiceName(); if (serviceName == null) { serviceName = d.getClass().getSimpleName(); } detectors.put(serviceName, d.getClass().getName()); } m_detectors = new LinkedHashMap<String,String>(); for (Entry<String,String> e : detectors.entrySet()) { m_detectors.put(e.getValue(), e.getKey()); } } return m_detectors; } /** * <p>getPolicyTypes</p> * * @return a {@link java.util.Map} object. */ public Map<String, String> getPolicyTypes() { if (m_policies == null) { Map<String,String> policies = new TreeMap<String,String>(); for (OnmsPolicy p : m_serviceRegistry.findProviders(OnmsPolicy.class)) { String policyName = p.getClass().getSimpleName(); if (p.getClass().isAnnotationPresent(Policy.class)) { Policy annotation = p.getClass().getAnnotation(Policy.class); if (annotation.value() != null && annotation.value().length() > 0) { policyName = annotation.value(); } } policies.put(policyName, p.getClass().getName()); } m_policies = new LinkedHashMap<String,String>(); for (Entry<String,String> e : policies.entrySet()) { m_policies.put(e.getValue(), e.getKey()); } } return m_policies; } /** * <p>getWrappers</p> * * @return a {@link java.util.Map} object. */ public Map<String,PluginWrapper> getWrappers() { if (m_wrappers == null && m_policies != null && m_detectors != null) { m_wrappers = new HashMap<String,PluginWrapper>(m_policies.size()); for (String key : m_policies.keySet()) { try { PluginWrapper wrapper = new PluginWrapper(key); m_wrappers.put(key, wrapper); } catch (Throwable e) { log().warn("unable to wrap " + key, e); } } for (String key : m_detectors.keySet()) { try { PluginWrapper wrapper = new PluginWrapper(key); m_wrappers.put(key, wrapper); } catch (Throwable e) { log().warn("unable to wrap " + key, e); } } } return m_wrappers; } private void normalizePluginConfigs(ForeignSource fs) { for (PluginConfig pc : fs.getDetectors()) { normalizePluginConfig(pc); } for (PluginConfig pc : fs.getPolicies()) { normalizePluginConfig(pc); } } private void normalizePluginConfig(PluginConfig pc) { if (m_wrappers.containsKey(pc.getPluginClass())) { PluginWrapper w = m_wrappers.get(pc.getPluginClass()); if (w != null) { Map<String,String> parameters = pc.getParameterMap(); Map<String,Set<String>> required = w.getRequiredItems(); for (String key : required.keySet()) { String value = ""; if (!parameters.containsKey(key)) { if (required.get(key).size() > 0) { value = required.get(key).iterator().next(); } pc.addParameter(key, value); } } } } } private ThreadCategory log() { return ThreadCategory.getInstance(DefaultForeignSourceService.class); } }