/*******************************************************************************
* 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.rtc;
import java.net.InetAddress;
import java.text.ParseException;
import java.util.List;
import org.opennms.core.utils.InetAddressUtils;
import org.opennms.core.utils.ThreadCategory;
import org.opennms.netmgt.EventConstants;
import org.opennms.netmgt.xml.event.Event;
import org.opennms.netmgt.xml.event.Parm;
import org.opennms.netmgt.xml.event.Value;
/**
* <P>
* The DataUpdater is created for each event by the event receiver. Depending on
* the event UEI, relevant information is read from the event and the
* DataManager informed so that data maintained by the RTC is kept up-to-date
* </P>
*
* @author <A HREF="mailto:sowmya@opennms.org">Sowmya Nataraj </A>
* @author <A HREF="http://www.opennms.org">OpenNMS.org </A>
*/
final class DataUpdater implements Runnable {
/**
* The event from which data is to be read
*/
private Event m_event;
/**
* If it is a nodeGainedService, create a new entry in the map
*/
private void handleNodeGainedService(long nodeid, InetAddress ip, String svcName) {
ThreadCategory log = ThreadCategory.getInstance(DataUpdater.class);
if (nodeid == -1 || ip == null || svcName == null) {
log.warn(m_event.getUei() + " ignored - info incomplete - nodeid/ip/svc: " + nodeid + "/" + InetAddressUtils.str(ip) + "/" + svcName);
return;
}
DataManager dataMgr = RTCManager.getDataManager();
dataMgr.nodeGainedService(nodeid, ip, svcName);
if (log.isDebugEnabled())
log.debug(m_event.getUei() + " added " + nodeid + ": " + InetAddressUtils.str(ip) + ": " + svcName + " to data store");
}
/**
* If it is a nodeLostService, update downtime on the rtcnode
*/
private void handleNodeLostService(long nodeid, InetAddress ip, String svcName, long eventTime) {
ThreadCategory log = ThreadCategory.getInstance(DataUpdater.class);
if (nodeid == -1 || ip == null || svcName == null || eventTime == -1) {
log.warn(m_event.getUei() + " ignored - info incomplete - nodeid/ip/svc/eventtime: " + nodeid + "/" + InetAddressUtils.str(ip) + "/" + svcName + "/" + eventTime);
return;
}
DataManager dataMgr = RTCManager.getDataManager();
dataMgr.nodeLostService(nodeid, ip, svcName, eventTime);
if (log.isDebugEnabled())
log.debug("Added nodeLostService to nodeid: " + nodeid + " ip: " + InetAddressUtils.str(ip) + " svcName: " + svcName);
}
/**
* If it is an interfaceDown, update downtime on the appropriate rtcnodes
*/
private void handleInterfaceDown(long nodeid, InetAddress ip, long eventTime) {
ThreadCategory log = ThreadCategory.getInstance(DataUpdater.class);
if (nodeid == -1 || ip == null || eventTime == -1) {
log.warn(m_event.getUei() + " ignored - info incomplete - nodeid/ip/eventtime: " + nodeid + "/" + InetAddressUtils.str(ip) + "/" + eventTime);
return;
}
DataManager dataMgr = RTCManager.getDataManager();
dataMgr.interfaceDown(nodeid, ip, eventTime);
if (log.isDebugEnabled())
log.debug("Recorded interfaceDown for nodeid: " + nodeid + " ip: " + InetAddressUtils.str(ip));
}
/**
* If it is an nodeDown, update downtime on the appropriate rtcnodes
*/
private void handleNodeDown(long nodeid, long eventTime) {
ThreadCategory log = ThreadCategory.getInstance(DataUpdater.class);
if (nodeid == -1 || eventTime == -1) {
log.warn(m_event.getUei() + " ignored - info incomplete - nodeid/eventtime: " + nodeid + "/" + eventTime);
return;
}
DataManager dataMgr = RTCManager.getDataManager();
dataMgr.nodeDown(nodeid, eventTime);
if (log.isDebugEnabled())
log.debug("Recorded nodeDown for nodeid: " + nodeid);
}
/**
* If it is a nodeUp, update regained time on the appropriate rtcnodes
*/
private void handleNodeUp(long nodeid, long eventTime) {
ThreadCategory log = ThreadCategory.getInstance(DataUpdater.class);
if (nodeid == -1 || eventTime == -1) {
log.warn(m_event.getUei() + " ignored - info incomplete - nodeid/eventtime: " + nodeid + "/" + eventTime);
return;
}
DataManager dataMgr = RTCManager.getDataManager();
dataMgr.nodeUp(nodeid, eventTime);
if (log.isDebugEnabled())
log.debug("Recorded nodeUp for nodeid: " + nodeid);
}
/**
* If it is an interfaceUp, update regained time on the appropriate rtcnodes
*/
private void handleInterfaceUp(long nodeid, InetAddress ip, long eventTime) {
ThreadCategory log = ThreadCategory.getInstance(DataUpdater.class);
if (nodeid == -1 || ip == null || eventTime == -1) {
log.warn(m_event.getUei() + " ignored - info incomplete - nodeid/ip/eventtime: " + nodeid + "/" + InetAddressUtils.str(ip) + "/" + eventTime);
return;
}
DataManager dataMgr = RTCManager.getDataManager();
dataMgr.interfaceUp(nodeid, ip, eventTime);
if (log.isDebugEnabled())
log.debug("Recorded interfaceUp for nodeid: " + nodeid + " ip: " + InetAddressUtils.str(ip));
}
/**
* If it is a nodeRegainedService, update downtime on the rtcnode
*/
private void handleNodeRegainedService(long nodeid, InetAddress ip, String svcName, long eventTime) {
ThreadCategory log = ThreadCategory.getInstance(DataUpdater.class);
if (nodeid == -1 || ip == null || svcName == null || eventTime == -1) {
log.warn(m_event.getUei() + " ignored - info incomplete - nodeid/ip/svc/eventtime: " + nodeid + "/" + InetAddressUtils.str(ip) + "/" + svcName + "/" + eventTime);
return;
}
DataManager dataMgr = RTCManager.getDataManager();
dataMgr.nodeRegainedService(nodeid, ip, svcName, eventTime);
if (log.isDebugEnabled())
log.debug("Added nodeRegainedService to nodeid: " + nodeid + " ip: " + InetAddressUtils.str(ip) + " svcName: " + svcName);
}
/**
* If it is a serviceDeleted, remove corresponding RTC nodes from the map
*/
private void handleServiceDeleted(long nodeid, InetAddress ip, String svcName) {
ThreadCategory log = ThreadCategory.getInstance(DataUpdater.class);
if (nodeid == -1 || ip == null || svcName == null) {
log.warn(m_event.getUei() + " ignored - info incomplete - nodeid/ip/svc: " + nodeid + "/" + InetAddressUtils.str(ip) + "/" + svcName);
return;
}
DataManager dataMgr = RTCManager.getDataManager();
dataMgr.serviceDeleted(nodeid, ip, svcName);
if (log.isDebugEnabled())
log.debug(m_event.getUei() + " deleted " + nodeid + ": " + InetAddressUtils.str(ip) + ": " + svcName + " from data store");
}
/**
* Record the interfaceReparented info in the datastore
*/
private void handleInterfaceReparented(InetAddress ip, List<Parm> list) {
ThreadCategory log = ThreadCategory.getInstance(DataUpdater.class);
if (ip == null || list == null) {
log.warn(m_event.getUei() + " ignored - info incomplete - ip/parms: " + InetAddressUtils.str(ip) + "/" + list);
return;
}
// old node ID
long oldNodeId = -1;
// new node ID
long newNodeId = -1;
String parmName = null;
Value parmValue = null;
String parmContent = null;
for (Parm parm : list) {
parmName = parm.getParmName();
parmValue = parm.getValue();
if (parmValue == null)
continue;
else
parmContent = parmValue.getContent();
// old node ID
if (parmName.equals(EventConstants.PARM_OLD_NODEID)) {
String temp = parmContent;
try {
oldNodeId = Long.valueOf(temp).longValue();
} catch (NumberFormatException nfe) {
log.warn("Parameter " + EventConstants.PARM_OLD_NODEID + " cannot be non-numeric", nfe);
oldNodeId = -1;
}
}
// new node ID
else if (parmName.equals(EventConstants.PARM_NEW_NODEID)) {
String temp = parmContent;
try {
newNodeId = Long.valueOf(temp).longValue();
} catch (NumberFormatException nfe) {
log.warn("Parameter " + EventConstants.PARM_NEW_NODEID + " cannot be non-numeric", nfe);
newNodeId = -1;
}
}
}
if (oldNodeId == -1 || newNodeId == -1) {
log.warn(m_event.getUei() + " did not have all required information for " + InetAddressUtils.str(ip) + " Values contained old nodeid: " + oldNodeId + " new nodeid: " + newNodeId);
} else {
DataManager dataMgr = RTCManager.getDataManager();
dataMgr.interfaceReparented(ip, oldNodeId, newNodeId);
if (log.isDebugEnabled())
log.debug(m_event.getUei() + " reparented ip: " + InetAddressUtils.str(ip) + " from " + oldNodeId + " to " + newNodeId);
}
}
/**
* Inform the data sender of the new listener
*/
private void handleRtcSubscribe(List<Parm> list) {
ThreadCategory log = ThreadCategory.getInstance(DataUpdater.class);
if (list == null) {
log.warn(m_event.getUei() + " ignored - info incomplete (null event parms)");
return;
}
String url = null;
String clabel = null;
String user = null;
String passwd = null;
String parmName = null;
Value parmValue = null;
String parmContent = null;
for (Parm parm : list) {
parmName = parm.getParmName();
parmValue = parm.getValue();
if (parmValue == null)
continue;
else
parmContent = parmValue.getContent();
if (parmName.equals(EventConstants.PARM_URL)) {
url = parmContent;
}
else if (parmName.equals(EventConstants.PARM_CAT_LABEL)) {
clabel = parmContent;
}
else if (parmName.equals(EventConstants.PARM_USER)) {
user = parmContent;
}
else if (parmName.equals(EventConstants.PARM_PASSWD)) {
passwd = parmContent;
}
}
// check that we got all required parms
if (url == null || clabel == null || user == null || passwd == null) {
log.warn(m_event.getUei() + " did not have all required information. Values contained url: " + url + " catlabel: " + clabel + " user: " + user + "passwd: " + passwd);
} else {
RTCManager.getInstance().getDataSender().subscribe(url, clabel, user, passwd);
if (log.isDebugEnabled())
log.debug(m_event.getUei() + " subscribed " + url + ": " + clabel + ": " + user);
}
}
/**
* Inform the data sender of the listener unsubscribing
*/
private void handleRtcUnsubscribe(List<Parm> list) {
ThreadCategory log = ThreadCategory.getInstance(DataUpdater.class);
if (list == null) {
log.warn(m_event.getUei() + " ignored - info incomplete (null event parms)");
return;
}
String url = null;
String parmName = null;
Value parmValue = null;
String parmContent = null;
for (Parm parm : list) {
parmName = parm.getParmName();
parmValue = parm.getValue();
if (parmValue == null)
continue;
else
parmContent = parmValue.getContent();
if (parmName.equals(EventConstants.PARM_URL)) {
url = parmContent;
}
}
// check that we got the required parameter
if (url == null) {
log.warn(m_event.getUei() + " did not have required information. Value of url: " + url);
} else {
RTCManager.getInstance().getDataSender().unsubscribe(url);
if (log.isDebugEnabled())
log.debug(m_event.getUei() + " unsubscribed " + url);
}
}
/**
* If it is a assetInfoChanged method, update RTC
*/
private void handleAssetInfoChangedEvent(long nodeid) {
ThreadCategory log = ThreadCategory.getInstance(DataUpdater.class);
DataManager dataMgr = RTCManager.getDataManager();
dataMgr.assetInfoChanged(nodeid);
if (log.isDebugEnabled())
log.debug(m_event.getUei() + " asset info changed for node " + nodeid);
}
/**
* If a node's surveillance category membership changed,
* update RTC since RTC categories may include surveillance
* categories via "categoryName" or "catinc*" rules
*/
private void handleNodeCategoryMembershipChanged(long nodeid) {
ThreadCategory log = ThreadCategory.getInstance(DataUpdater.class);
DataManager dataMgr = RTCManager.getDataManager();
dataMgr.nodeCategoryMembershipChanged(nodeid);
if (log.isDebugEnabled())
log.debug(m_event.getUei() + " surveillance category membership changed for node " + nodeid);
}
/**
* Read the event UEI, node ID, interface and service - depending on the UEI,
* read event parms, if necessary, and call appropriate methods on the data
* manager to update data
*/
private void processEvent() {
ThreadCategory log = ThreadCategory.getInstance(DataUpdater.class);
if (m_event == null) {
if (log.isDebugEnabled())
log.debug("Event is null, nothing to process");
return;
}
String eventUEI = m_event.getUei();
if (eventUEI == null) {
// huh? should only get registered events
if (log.isDebugEnabled())
log.debug("Event received with null UEI, ignoring event");
return;
}
long nodeid = -1;
if (m_event.hasNodeid()) {
nodeid = m_event.getNodeid();
}
InetAddress ip = m_event.getInterfaceAddress();
String svcName = m_event.getService();
long eventTime = -1;
String eventTimeStr = m_event.getTime();
try {
java.util.Date date = EventConstants.parseToDate(eventTimeStr);
eventTime = date.getTime();
} catch (ParseException pe) {
log.warn("Failed to convert time " + eventTime + " to java.util.Date, Setting current time instead", pe);
eventTime = (new java.util.Date()).getTime();
}
if (log.isDebugEnabled())
log.debug("Event UEI: " + eventUEI + "\tnodeid: " + nodeid + "\tip: " + InetAddressUtils.str(ip) + "\tsvcName: " + svcName + "\teventTime: " + eventTimeStr);
//
//
// Check for any of the following UEIs:
//
// nodeGainedService
// nodeLostService
// interfaceDown
// nodeDown
// nodeUp
// interfaceUp
// nodeRegainedService
// serviceDeleted
// interfaceReparented
// subscribe
// unsubscribe
//
if (eventUEI.equals(EventConstants.NODE_GAINED_SERVICE_EVENT_UEI)) {
handleNodeGainedService(nodeid, ip, svcName);
} else if (eventUEI.equals(EventConstants.NODE_LOST_SERVICE_EVENT_UEI)) {
handleNodeLostService(nodeid, ip, svcName, eventTime);
} else if (eventUEI.equals(EventConstants.INTERFACE_DOWN_EVENT_UEI)) {
handleInterfaceDown(nodeid, ip, eventTime);
} else if (eventUEI.equals(EventConstants.NODE_DOWN_EVENT_UEI)) {
handleNodeDown(nodeid, eventTime);
} else if (eventUEI.equals(EventConstants.NODE_UP_EVENT_UEI)) {
handleNodeUp(nodeid, eventTime);
} else if (eventUEI.equals(EventConstants.INTERFACE_UP_EVENT_UEI)) {
handleInterfaceUp(nodeid, ip, eventTime);
} else if (eventUEI.equals(EventConstants.NODE_REGAINED_SERVICE_EVENT_UEI)) {
handleNodeRegainedService(nodeid, ip, svcName, eventTime);
} else if (eventUEI.equals(EventConstants.SERVICE_DELETED_EVENT_UEI)) {
handleServiceDeleted(nodeid, ip, svcName);
} else if (eventUEI.equals(EventConstants.SERVICE_UNMANAGED_EVENT_UEI)) {
handleServiceDeleted(nodeid, ip, svcName);
} else if (eventUEI.equals(EventConstants.INTERFACE_REPARENTED_EVENT_UEI)) {
handleInterfaceReparented(ip, m_event.getParmCollection());
} else if (eventUEI.equals(EventConstants.RTC_SUBSCRIBE_EVENT_UEI)) {
handleRtcSubscribe(m_event.getParmCollection());
} else if (eventUEI.equals(EventConstants.RTC_UNSUBSCRIBE_EVENT_UEI)) {
handleRtcUnsubscribe(m_event.getParmCollection());
} else if (eventUEI.equals(EventConstants.ASSET_INFO_CHANGED_EVENT_UEI)) {
handleAssetInfoChangedEvent(nodeid);
} else if (eventUEI.equals(EventConstants.NODE_CATEGORY_MEMBERSHIP_CHANGED_EVENT_UEI)) {
handleNodeCategoryMembershipChanged(nodeid);
} else {
if (log.isDebugEnabled())
log.debug("Event subscribed for not handled?!: " + eventUEI);
}
RTCManager.getInstance().incrementCounter();
}
/**
* Constructs the DataUpdater object
*
* @param event a {@link org.opennms.netmgt.xml.event.Event} object.
*/
public DataUpdater(Event event) {
m_event = event;
}
/**
* Process the event depending on the UEI and update date
*/
public void run() {
ThreadCategory log = ThreadCategory.getInstance(DataUpdater.class);
try {
processEvent();
} catch (Throwable t) {
log.warn("Unexpected exception processing event", t);
}
}
}