<commit_before>/*
 * This file is part of the OpenNMS(R) Application.
 *
 * OpenNMS(R) is Copyright (C) 2008 The OpenNMS Group, Inc.  All rights reserved.
 * OpenNMS(R) is a derivative work, containing both original code, included code and modified
 * code that was published under the GNU General Public License. Copyrights for modified
 * and included code are below.
 *
 * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc.
 *
 * Original code base Copyright (C) 1999-2001 Oculan Corp.  All rights reserved.
 *
 * This program 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 2 of the License, or
 * (at your option) any later version.
 *
 * 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.
 *
 * For more information contact:
 * OpenNMS Licensing       <<EMAIL>>
 *     http://www.opennms.org/
 *     http://www.opennms.com/
 */
package org.opennms.netmgt.provision.service;


import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Category;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.opennms.core.utils.ThreadCategory;
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.dao.SnmpInterfaceDao;
import org.opennms.netmgt.model.EntityVisitor;
import org.opennms.netmgt.model.OnmsCategory;
import org.opennms.netmgt.model.OnmsDistPoller;
import org.opennms.netmgt.model.OnmsIpInterface;
import org.opennms.netmgt.model.OnmsMonitoredService;
import org.opennms.netmgt.model.OnmsNode;
import org.opennms.netmgt.model.OnmsServiceType;
import org.opennms.netmgt.model.OnmsSnmpInterface;
import org.opennms.netmgt.model.PathElement;
import org.opennms.netmgt.model.events.AddEventVisitor;
import org.opennms.netmgt.model.events.DeleteEventVisitor;
import org.opennms.netmgt.model.events.EventForwarder;
import org.opennms.netmgt.provision.ServiceDetector;
import org.opennms.netmgt.provision.persist.ForeignSourceRepository;
import org.opennms.netmgt.provision.persist.ForeignSourceRepositoryException;
import org.opennms.netmgt.provision.persist.OnmsNodeRequisition;
import org.opennms.netmgt.provision.persist.foreignsource.ForeignSource;
import org.opennms.netmgt.provision.persist.foreignsource.PluginConfig;
import org.opennms.netmgt.provision.persist.requisition.Requisition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

/**
 * DefaultProvisionService
 *
 * @author brozow
 */
@Service
public class DefaultProvisionService implements ProvisionService {
    
    @Autowired
    private DistPollerDao m_distPollerDao;
    
    @Autowired
    private NodeDao m_nodeDao;
    
    @Autowired
    private IpInterfaceDao m_ipInterfaceDao;
    
    @Autowired
    private SnmpInterfaceDao m_snmpInterfaceDao;
    
    @Autowired
    private MonitoredServiceDao m_monitoredServiceDao;
    
    @Autowired
    private ServiceTypeDao m_serviceTypeDao;
    
    @Autowired
    private CategoryDao m_categoryDao;
    
    @Autowired
    @Qualifier("transactionAware")
    private EventForwarder m_eventForwarder;
    
    @Autowired
    @Qualifier("deployed")
    private ForeignSourceRepository m_foreignSourceRepository;
    
    @Autowired
    private PluginRegistry m_pluginRegistry;
    
    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>>();

    @Transactional
    public void insertNode(OnmsNode node) {
        
        OnmsDistPoller distPoller = m_distPollerDao.get("localhost");

        node.setDistPoller(distPoller);
        m_nodeDao.save(node);

        EntityVisitor eventAccumlator = new AddEventVisitor(m_eventForwarder);

        node.visit(eventAccumlator);
        
        //TODO: Update node in schedule
    }
    
    @Transactional
    public void updateNode(OnmsNode scannedNode, boolean x, boolean xx) {
        
        OnmsNode dbNode = m_nodeDao.getHierarchy(scannedNode.getId());

        dbNode.mergeNode(scannedNode, m_eventForwarder);
    
        m_nodeDao.update(dbNode);
        
        //TODO: update the node in the scheduledList of Nodes
        
    }

    @Transactional
    public void deleteNode(Integer nodeId) {
        
        OnmsNode node = m_nodeDao.get(nodeId);
        if (node != null) {
    
            m_nodeDao.delete(node);
    
            node.visit(new DeleteEventVisitor(m_eventForwarder));
        }
        
        //TODO: Should remove the node from the scheduled list of nodes
    
    }
    
    private void assertNotNull(Object o, String format, Object... args) {
        if (o == null) {
            throw new IllegalArgumentException(String.format(format, args));
        }
    }
    
    
    
    public OnmsIpInterface updateIpInterfaceAttributes(Integer nodeId, OnmsIpInterface scannedIface) {
        if (scannedIface.getSnmpInterface() != null) {
            scannedIface.setSnmpInterface(updateSnmpInterfaceAttributes(nodeId, scannedIface.getSnmpInterface()));
        }
        
        OnmsIpInterface dbIface = m_ipInterfaceDao.findByNodeIdAndIpAddress(nodeId, scannedIface.getIpAddress());
        if (dbIface != null) {
            dbIface.mergeInterfaceAttributes(scannedIface);
            m_ipInterfaceDao.save(dbIface);
            return dbIface;
        } else {
            OnmsNode dbNode = m_nodeDao.get(nodeId);
            assertNotNull(dbNode, "no node found with nodeId %d", nodeId);
            dbNode.addIpInterface(scannedIface);
            m_nodeDao.update(dbNode);
            AddEventVisitor visitor = new AddEventVisitor(m_eventForwarder);
            scannedIface.visit(visitor);
            return scannedIface;
        }

    }

    public OnmsSnmpInterface updateSnmpInterfaceAttributes(Integer nodeId, OnmsSnmpInterface snmpInterface) {
        OnmsSnmpInterface dbSnmpIface = m_snmpInterfaceDao.findByNodeIdAndIfIndex(nodeId, snmpInterface.getIfIndex());
        if (dbSnmpIface != null) {
            // update the interface that was found
            dbSnmpIface.mergeSnmpInterfaceAttributes(snmpInterface);
            m_snmpInterfaceDao.update(dbSnmpIface);
            return dbSnmpIface;
        } else {
            // add the interface to the node, if it wasn't found
            OnmsNode dbNode = m_nodeDao.get(nodeId);
            assertNotNull(dbNode, "no node found with nodeId %d", nodeId);
            dbNode.addSnmpInterface(snmpInterface);
            m_nodeDao.update(dbNode);
            return snmpInterface;
        }
    }

    public OnmsMonitoredService addMonitoredService(Integer ipInterfaceId, String svcName) {
        OnmsIpInterface iface = m_ipInterfaceDao.get(ipInterfaceId);
        assertNotNull(iface, "could not find interface with id %d", ipInterfaceId);
        OnmsServiceType svcType = m_serviceTypeDao.findByName(svcName);
        if (svcType == null) {
            svcType = new OnmsServiceType(svcName);
            m_serviceTypeDao.save(svcType);
        }
        
        // this adds the service to the interface as a side effect
        OnmsMonitoredService svc = new OnmsMonitoredService(iface, svcType);
        
        m_ipInterfaceDao.save(iface);
        
        return svc;
    }

    public OnmsMonitoredService addMonitoredService(Integer nodeId, String ipAddress, String svcName) {
        OnmsIpInterface iface = m_ipInterfaceDao.findByNodeIdAndIpAddress(nodeId, ipAddress);
        assertNotNull(iface, "could not find interface with nodeid %d and ipAddr %s", nodeId, ipAddress);
        OnmsServiceType svcType = m_serviceTypeDao.findByName(svcName);
        if (svcType == null) {
            svcType = new OnmsServiceType(svcName);
            m_serviceTypeDao.save(svcType);
        }
        
        // this adds the service to the interface as a side effect
        OnmsMonitoredService svc = new OnmsMonitoredService(iface, svcType);
        
        m_ipInterfaceDao.save(iface);
        
        return svc;
    }

    public void clearCache() {
        m_nodeDao.clear();
    }
    
    @Transactional
    public OnmsDistPoller createDistPollerIfNecessary(String dpName, String dpAddr) {<commit_msg>make sure we handle services that already exist<commit_after>/*
 * This file is part of the OpenNMS(R) Application.
 *
 * OpenNMS(R) is Copyright (C) 2008 The OpenNMS Group, Inc.  All rights reserved.
 * OpenNMS(R) is a derivative work, containing both original code, included code and modified
 * code that was published under the GNU General Public License. Copyrights for modified
 * and included code are below.
 *
 * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc.
 *
 * Original code base Copyright (C) 1999-2001 Oculan Corp.  All rights reserved.
 *
 * This program 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 2 of the License, or
 * (at your option) any later version.
 *
 * 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.
 *
 * For more information contact:
 * OpenNMS Licensing       <<EMAIL>>
 *     http://www.opennms.org/
 *     http://www.opennms.com/
 */
package org.opennms.netmgt.provision.service;


import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Category;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.opennms.core.utils.ThreadCategory;
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.dao.SnmpInterfaceDao;
import org.opennms.netmgt.model.EntityVisitor;
import org.opennms.netmgt.model.OnmsCategory;
import org.opennms.netmgt.model.OnmsDistPoller;
import org.opennms.netmgt.model.OnmsIpInterface;
import org.opennms.netmgt.model.OnmsMonitoredService;
import org.opennms.netmgt.model.OnmsNode;
import org.opennms.netmgt.model.OnmsServiceType;
import org.opennms.netmgt.model.OnmsSnmpInterface;
import org.opennms.netmgt.model.PathElement;
import org.opennms.netmgt.model.events.AddEventVisitor;
import org.opennms.netmgt.model.events.DeleteEventVisitor;
import org.opennms.netmgt.model.events.EventForwarder;
import org.opennms.netmgt.provision.ServiceDetector;
import org.opennms.netmgt.provision.persist.ForeignSourceRepository;
import org.opennms.netmgt.provision.persist.ForeignSourceRepositoryException;
import org.opennms.netmgt.provision.persist.OnmsNodeRequisition;
import org.opennms.netmgt.provision.persist.foreignsource.ForeignSource;
import org.opennms.netmgt.provision.persist.foreignsource.PluginConfig;
import org.opennms.netmgt.provision.persist.requisition.Requisition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

/**
 * DefaultProvisionService
 *
 * @author brozow
 */
@Service
public class DefaultProvisionService implements ProvisionService {
    
    @Autowired
    private DistPollerDao m_distPollerDao;
    
    @Autowired
    private NodeDao m_nodeDao;
    
    @Autowired
    private IpInterfaceDao m_ipInterfaceDao;
    
    @Autowired
    private SnmpInterfaceDao m_snmpInterfaceDao;
    
    @Autowired
    private MonitoredServiceDao m_monitoredServiceDao;
    
    @Autowired
    private ServiceTypeDao m_serviceTypeDao;
    
    @Autowired
    private CategoryDao m_categoryDao;
    
    @Autowired
    @Qualifier("transactionAware")
    private EventForwarder m_eventForwarder;
    
    @Autowired
    @Qualifier("deployed")
    private ForeignSourceRepository m_foreignSourceRepository;
    
    @Autowired
    private PluginRegistry m_pluginRegistry;
    
    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>>();

    @Transactional
    public void insertNode(OnmsNode node) {
        
        OnmsDistPoller distPoller = m_distPollerDao.get("localhost");

        node.setDistPoller(distPoller);
        m_nodeDao.save(node);

        EntityVisitor eventAccumlator = new AddEventVisitor(m_eventForwarder);

        node.visit(eventAccumlator);
        
        //TODO: Update node in schedule
    }
    
    @Transactional
    public void updateNode(OnmsNode scannedNode, boolean x, boolean xx) {
        
        OnmsNode dbNode = m_nodeDao.getHierarchy(scannedNode.getId());

        dbNode.mergeNode(scannedNode, m_eventForwarder);
    
        m_nodeDao.update(dbNode);
        
        //TODO: update the node in the scheduledList of Nodes
        
    }

    @Transactional
    public void deleteNode(Integer nodeId) {
        
        OnmsNode node = m_nodeDao.get(nodeId);
        if (node != null) {
    
            m_nodeDao.delete(node);
    
            node.visit(new DeleteEventVisitor(m_eventForwarder));
        }
        
        //TODO: Should remove the node from the scheduled list of nodes
    
    }
    
    private void assertNotNull(Object o, String format, Object... args) {
        if (o == null) {
            throw new IllegalArgumentException(String.format(format, args));
        }
    }
    
    
    
    public OnmsIpInterface updateIpInterfaceAttributes(Integer nodeId, OnmsIpInterface scannedIface) {
        if (scannedIface.getSnmpInterface() != null) {
            scannedIface.setSnmpInterface(updateSnmpInterfaceAttributes(nodeId, scannedIface.getSnmpInterface()));
        }
        
        OnmsIpInterface dbIface = m_ipInterfaceDao.findByNodeIdAndIpAddress(nodeId, scannedIface.getIpAddress());
        if (dbIface != null) {
            dbIface.mergeInterfaceAttributes(scannedIface);
            m_ipInterfaceDao.save(dbIface);
            return dbIface;
        } else {
            OnmsNode dbNode = m_nodeDao.get(nodeId);
            assertNotNull(dbNode, "no node found with nodeId %d", nodeId);
            dbNode.addIpInterface(scannedIface);
            m_nodeDao.update(dbNode);
            AddEventVisitor visitor = new AddEventVisitor(m_eventForwarder);
            scannedIface.visit(visitor);
            return scannedIface;
        }

    }

    public OnmsSnmpInterface updateSnmpInterfaceAttributes(Integer nodeId, OnmsSnmpInterface snmpInterface) {
        OnmsSnmpInterface dbSnmpIface = m_snmpInterfaceDao.findByNodeIdAndIfIndex(nodeId, snmpInterface.getIfIndex());
        if (dbSnmpIface != null) {
            // update the interface that was found
            dbSnmpIface.mergeSnmpInterfaceAttributes(snmpInterface);
            m_snmpInterfaceDao.update(dbSnmpIface);
            return dbSnmpIface;
        } else {
            // add the interface to the node, if it wasn't found
            OnmsNode dbNode = m_nodeDao.get(nodeId);
            assertNotNull(dbNode, "no node found with nodeId %d", nodeId);
            dbNode.addSnmpInterface(snmpInterface);
            m_nodeDao.update(dbNode);
            return snmpInterface;
        }
    }

    public OnmsMonitoredService addMonitoredService(Integer ipInterfaceId, String svcName) {
        OnmsIpInterface iface = m_ipInterfaceDao.get(ipInterfaceId);
        assertNotNull(iface, "could not find interface with id %d", ipInterfaceId);
        OnmsServiceType svcType = m_serviceTypeDao.findByName(svcName);
        if (svcType == null) {
            svcType = new OnmsServiceType(svcName);
            m_serviceTypeDao.save(svcType);
        }
        
        OnmsMonitoredService svc = iface.getMonitoredServiceByServiceType(svcName);
        if (svc != null) {
            m_monitoredServiceDao.saveOrUpdate(svc);
        } else {
        
            // this adds the service to the interface as a side effect
            svc = new OnmsMonitoredService(iface, svcType);
            svc.setStatus("A");
            m_ipInterfaceDao.saveOrUpdate(iface);
            AddEventVisitor visitor = new AddEventVisitor(m_eventForwarder);
            svc.visit(visitor);
        }

        
        return svc;
    }

    public OnmsMonitoredService addMonitoredService(Integer nodeId, String ipAddress, String svcName) {
        OnmsIpInterface iface = m_ipInterfaceDao.findByNodeIdAndIpAddress(nodeId, ipAddress);
        assertNotNull(iface, "could not find interface with nodeid %d and ipAddr %s", nodeId, ipAddress);
        OnmsServiceType svcType = m_serviceTypeDao.findByName(svcName);
        if (svcType == null) {
            svcType = new OnmsServiceType(svcName);
            m_serviceTypeDao.save(svcType);
        }
        
        OnmsMonitoredService svc = iface.getMonitoredServiceByServiceType(svcName);
        if (svc != null) {
            m_monitoredServiceDao.saveOrUpdate(svc);
        } else {
        
            // this adds the service to the interface as a side effect
            svc = new OnmsMonitoredService(iface, svcType);
            svc.setStatus("A");
            m_ipInterfaceDao.saveOrUpdate(iface);
            AddEventVisitor visitor = new AddEventVisitor(m_eventForwarder);
            svc.visit(visitor);
        }

        
        return svc;
    }

    public void clearCache() {
        m_nodeDao.clear();
    }
    
    @Transactional
    public OnmsDistPoller createDistPollerIfNecessary(String dpName, String dpAddr) {
{'fraction_non_alphanumeric': 0.08019945979638479, 'fraction_numerical': 0.002908788697278205, 'mean_word_length': 3.1982119494112515, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6993511', 'n_tokens_mistral': 5790, 'n_tokens_neox': 5809, 'n_words': 1301}