/******************************************************************************* * 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.importer; import java.io.IOException; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.opennms.core.utils.InetAddressUtils; import org.opennms.core.utils.ThreadCategory; import org.opennms.netmgt.importer.config.Node; import org.opennms.netmgt.dao.AssetRecordDao; import org.opennms.netmgt.dao.CategoryDao; import org.opennms.netmgt.dao.DistPollerDao; import org.opennms.netmgt.dao.IpInterfaceDao; import org.opennms.netmgt.dao.MonitoredServiceDao; import org.opennms.netmgt.dao.NodeDao; import org.opennms.netmgt.dao.ServiceTypeDao; import org.opennms.netmgt.eventd.EventUtil; import org.opennms.netmgt.importer.operations.DefaultImportStatistics; import org.opennms.netmgt.importer.operations.DeleteOperation; import org.opennms.netmgt.importer.operations.ImportOperationFactory; import org.opennms.netmgt.importer.operations.ImportOperationsManager; import org.opennms.netmgt.importer.operations.ImportStatistics; import org.opennms.netmgt.importer.operations.InsertOperation; import org.opennms.netmgt.importer.operations.UpdateOperation; import org.opennms.netmgt.importer.specification.AbstractImportVisitor; import org.opennms.netmgt.importer.specification.SpecFile; import org.opennms.netmgt.model.OnmsCategory; import org.opennms.netmgt.model.OnmsDistPoller; import org.opennms.netmgt.model.OnmsIpInterface; import org.opennms.netmgt.model.OnmsNode; import org.opennms.netmgt.model.OnmsServiceType; import org.opennms.netmgt.model.PathElement; import org.opennms.netmgt.xml.event.Event; import org.springframework.core.io.Resource; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate; /** * <p>BaseImporter class.</p> * * @author ranger * @version $Id: $ */ public class BaseImporter implements ImportOperationFactory { protected TransactionTemplate m_transTemplate; protected DistPollerDao m_distPollerDao; private NodeDao m_nodeDao; private IpInterfaceDao m_ipInterfaceDao; private ServiceTypeDao m_serviceTypeDao; private MonitoredServiceDao m_monitoredServiceDao; private AssetRecordDao m_assetRecordDao; private CategoryDao m_categoryDao; private final ThreadLocal<HashMap<String, OnmsServiceType>> m_typeCache = new ThreadLocal<HashMap<String, OnmsServiceType>>(); private final ThreadLocal<HashMap<String, OnmsCategory>> m_categoryCache = new ThreadLocal<HashMap<String, OnmsCategory>>(); private int m_scanThreads = 50; private int m_writeThreads = 4; //FIXME: We have a setTransactionTemplate and a setTransTemplate for the same field. /** * <p>setTransactionTemplate</p> * * @param transTemplate a {@link org.springframework.transaction.support.TransactionTemplate} object. */ public void setTransactionTemplate(TransactionTemplate transTemplate) { m_transTemplate = transTemplate; } /** * <p>getDistPollerDao</p> * * @return a {@link org.opennms.netmgt.dao.DistPollerDao} object. */ public DistPollerDao getDistPollerDao() { return m_distPollerDao; } /** * <p>setDistPollerDao</p> * * @param distPollerDao a {@link org.opennms.netmgt.dao.DistPollerDao} object. */ public void setDistPollerDao(DistPollerDao distPollerDao) { m_distPollerDao = distPollerDao; } /** * <p>getNodeDao</p> * * @return a {@link org.opennms.netmgt.dao.NodeDao} object. */ public NodeDao getNodeDao() { return m_nodeDao; } /** * <p>setNodeDao</p> * * @param nodeDao a {@link org.opennms.netmgt.dao.NodeDao} object. */ public void setNodeDao(NodeDao nodeDao) { m_nodeDao = nodeDao; } /** * <p>getIpInterfaceDao</p> * * @return a {@link org.opennms.netmgt.dao.IpInterfaceDao} object. */ public IpInterfaceDao getIpInterfaceDao() { return m_ipInterfaceDao; } /** * <p>setIpInterfaceDao</p> * * @param ipInterfaceDao a {@link org.opennms.netmgt.dao.IpInterfaceDao} object. */ public void setIpInterfaceDao(IpInterfaceDao ipInterfaceDao) { m_ipInterfaceDao = ipInterfaceDao; } /** * <p>getMonitoredServiceDao</p> * * @return a {@link org.opennms.netmgt.dao.MonitoredServiceDao} object. */ public MonitoredServiceDao getMonitoredServiceDao() { return m_monitoredServiceDao; } /** * <p>setMonitoredServiceDao</p> * * @param monitoredServiceDao a {@link org.opennms.netmgt.dao.MonitoredServiceDao} object. */ public void setMonitoredServiceDao(MonitoredServiceDao monitoredServiceDao) { m_monitoredServiceDao = monitoredServiceDao; } /** * <p>getServiceTypeDao</p> * * @return a {@link org.opennms.netmgt.dao.ServiceTypeDao} object. */ public ServiceTypeDao getServiceTypeDao() { return m_serviceTypeDao; } /** * <p>setServiceTypeDao</p> * * @param serviceTypeDao a {@link org.opennms.netmgt.dao.ServiceTypeDao} object. */ public void setServiceTypeDao(ServiceTypeDao serviceTypeDao) { m_serviceTypeDao = serviceTypeDao; } /** * <p>getAssetRecordDao</p> * * @return a {@link org.opennms.netmgt.dao.AssetRecordDao} object. */ public AssetRecordDao getAssetRecordDao() { return m_assetRecordDao; } /** * <p>setAssetRecordDao</p> * * @param assetRecordDao a {@link org.opennms.netmgt.dao.AssetRecordDao} object. */ public void setAssetRecordDao(AssetRecordDao assetRecordDao) { m_assetRecordDao = assetRecordDao; } /** * <p>getTransTemplate</p> * * @return a {@link org.springframework.transaction.support.TransactionTemplate} object. */ public TransactionTemplate getTransTemplate() { return m_transTemplate; } /** * <p>setTransTemplate</p> * * @param transTemplate a {@link org.springframework.transaction.support.TransactionTemplate} object. */ public void setTransTemplate(TransactionTemplate transTemplate) { m_transTemplate = transTemplate; } /** {@inheritDoc} */ public InsertOperation createInsertOperation(String foreignSource, String foreignId, String nodeLabel, String building, String city) { InsertOperation insertOperation = new InsertOperation(foreignSource, foreignId, nodeLabel, building, city); insertOperation.setNodeDao(m_nodeDao); insertOperation.setDistPollerDao(m_distPollerDao); insertOperation.setServiceTypeDao(m_serviceTypeDao); insertOperation.setCategoryDao(m_categoryDao); insertOperation.setTypeCache(m_typeCache); insertOperation.setCategoryCache(m_categoryCache); return insertOperation; } /** {@inheritDoc} */ public UpdateOperation createUpdateOperation(Integer nodeId, String foreignSource, String foreignId, String nodeLabel, String building, String city) { UpdateOperation updateOperation = new UpdateOperation(nodeId, foreignSource, foreignId, nodeLabel, building, city); updateOperation.setNodeDao(m_nodeDao); updateOperation.setDistPollerDao(m_distPollerDao); updateOperation.setServiceTypeDao(m_serviceTypeDao); updateOperation.setCategoryDao(m_categoryDao); updateOperation.setTypeCache(m_typeCache); updateOperation.setCategoryCache(m_categoryCache); return updateOperation; } /** {@inheritDoc} */ public DeleteOperation createDeleteOperation(Integer nodeId, String foreignSource, String foreignId) { return new DeleteOperation(nodeId, foreignSource, foreignId, m_nodeDao); } /** * <p>importModelFromResource</p> * * @param resource a {@link org.springframework.core.io.Resource} object. * @throws java.io.IOException if any. * @throws org.opennms.netmgt.importer.ModelImportException if any. */ protected void importModelFromResource(Resource resource) throws IOException, ModelImportException { importModelFromResource(resource, new DefaultImportStatistics(), null); } /** * <p>importModelFromResource</p> * * @param resource a {@link org.springframework.core.io.Resource} object. * @param stats a {@link org.opennms.netmgt.importer.operations.ImportStatistics} object. * @param event a {@link org.opennms.netmgt.xml.event.Event} object. * @throws java.io.IOException if any. * @throws org.opennms.netmgt.importer.ModelImportException if any. */ protected void importModelFromResource(Resource resource, ImportStatistics stats, Event event) throws IOException, ModelImportException { stats.beginImporting(); stats.beginLoadingResource(resource); SpecFile specFile = new SpecFile(); specFile.loadResource(resource); stats.finishLoadingResource(resource); if (event != null && getEventForeignSource(event) != null) { specFile.setForeignSource(getEventForeignSource(event)); } stats.beginAuditNodes(); createDistPollerIfNecessary(); Map<String, Integer> foreignIdsToNodes = getForeignIdToNodeMap(specFile.getForeignSource()); ImportOperationsManager opsMgr = createImportOperationsManager(foreignIdsToNodes, stats); opsMgr.setForeignSource(specFile.getForeignSource()); opsMgr.setScanThreads(m_scanThreads); opsMgr.setWriteThreads(m_writeThreads); auditNodes(opsMgr, specFile); stats.finishAuditNodes(); opsMgr.persistOperations(m_transTemplate, getNodeDao()); stats.beginRelateNodes(); relateNodes(specFile); stats.finishRelateNodes(); stats.finishImporting(); } private String getEventForeignSource(Event event) { return EventUtil.getNamedParmValue("parm[foreignSource]", event); } /** * <p>createImportOperationsManager</p> * * @param foreignIdsToNodes a {@link java.util.Map} object. * @param stats a {@link org.opennms.netmgt.importer.operations.ImportStatistics} object. * @return a {@link org.opennms.netmgt.importer.operations.ImportOperationsManager} object. */ protected ImportOperationsManager createImportOperationsManager(Map<String, Integer> foreignIdsToNodes, ImportStatistics stats) { ImportOperationsManager opsMgr = new ImportOperationsManager(foreignIdsToNodes, this); opsMgr.setStats(stats); return opsMgr; } private void auditNodes(final ImportOperationsManager opsMgr, final SpecFile specFile) { m_transTemplate.execute(new TransactionCallback<Object>() { public Object doInTransaction(TransactionStatus status) { ImportAccountant accountant = new ImportAccountant(opsMgr); specFile.visitImport(accountant); return null; } }); } class NodeRelator extends AbstractImportVisitor { String m_foreignSource; public NodeRelator(String foreignSource) { m_foreignSource = foreignSource; } public void visitNode(final Node node) { m_transTemplate.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) { OnmsNode dbNode = findNodeByForeignId(m_foreignSource, node.getForeignId()); if (dbNode == null) { log().error("Error setting parent on node: "+node.getForeignId()+" node not in database"); return; } OnmsNode parent = findParent(node); OnmsIpInterface critIface = null; if (parent != null) { critIface = getCriticalInterface(parent); } log().info("Setting parent of node: "+dbNode+" to: "+parent); dbNode.setParent(parent); log().info("Setting criticalInterface of node: "+dbNode+" to: "+critIface); if (critIface == null) { dbNode.setPathElement(null); } else { final String ipAddress = InetAddressUtils.str(critIface.getIpAddress()); dbNode.setPathElement(new PathElement(ipAddress, "ICMP")); } getNodeDao().update(dbNode); } private OnmsIpInterface getCriticalInterface(OnmsNode parent) { OnmsIpInterface critIface = parent.getPrimaryInterface(); if (critIface != null) { return critIface; } return parent.getInterfaceWithService("ICMP"); } }); } private OnmsNode findParent(Node node) { if (node.getParentForeignId() != null) { return findNodeByForeignId(m_foreignSource, node.getParentForeignId()); } else if (node.getParentNodeLabel() != null) { return findNodeByNodeLabel(node.getParentNodeLabel()); } return null; } private OnmsNode findNodeByNodeLabel(String label) { Collection<OnmsNode> nodes = getNodeDao().findByLabel(label); if (nodes.size() == 1) { return nodes.iterator().next(); } log().error("Unable to locate a unique node using label "+label+" "+nodes.size()+" nodes found. Ignoring relationship."); return null; } private OnmsNode findNodeByForeignId(String foreignSource, String foreignId) { return getNodeDao().findByForeignId(foreignSource, foreignId); } }; private void relateNodes(SpecFile specFile) { specFile.visitImport(new NodeRelator(specFile.getForeignSource())); } /** * <p>log</p> * * @return a {@link org.opennms.core.utils.ThreadCategory} object. */ public ThreadCategory log() { return ThreadCategory.getInstance(getClass()); } private Map<String, Integer> getForeignIdToNodeMap(final String foreignSource) { return m_transTemplate.execute(new TransactionCallback<Map<String, Integer>>() { public Map<String,Integer> doInTransaction(TransactionStatus status) { return Collections.unmodifiableMap(getNodeDao().getForeignIdToNodeIdMap(foreignSource)); } }); } private OnmsDistPoller createDistPollerIfNecessary() { return m_transTemplate.execute(new TransactionCallback<OnmsDistPoller>() { public OnmsDistPoller doInTransaction(TransactionStatus status) { OnmsDistPoller distPoller = m_distPollerDao.get("localhost"); if (distPoller == null) { distPoller = new OnmsDistPoller("localhost", "127.0.0.1"); m_distPollerDao.save(distPoller); } return distPoller; } }); } /** * <p>getCategoryDao</p> * * @return a {@link org.opennms.netmgt.dao.CategoryDao} object. */ public CategoryDao getCategoryDao() { return m_categoryDao; } /** * <p>setCategoryDao</p> * * @param categoryDao a {@link org.opennms.netmgt.dao.CategoryDao} object. */ public void setCategoryDao(CategoryDao categoryDao) { m_categoryDao = categoryDao; } /** * <p>getScanThreads</p> * * @return a int. */ public int getScanThreads() { return m_scanThreads; } /** * <p>setScanThreads</p> * * @param poolSize a int. */ public void setScanThreads(int poolSize) { m_scanThreads = poolSize; } /** * <p>getWriteThreads</p> * * @return a int. */ public int getWriteThreads() { return m_writeThreads; } /** * <p>setWriteThreads</p> * * @param writeThreads a int. */ public void setWriteThreads(int writeThreads) { m_writeThreads = writeThreads; } }