//
// This file is part of the OpenNMS(R) Application.
//
// OpenNMS(R) is Copyright (C) 2002-2003 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.
//
// Modifications:
//
// 2009 May 14: added threshold config change handler for in-line thresholds processing
// 2004 Jan 06: Added support for SUSPEND_POLLING_SERVICE_EVENT_UEI and
// RESUME_POLLING_SERVICE_EVENT_UEI
// 2003 Nov 11: Merged changes from Rackspace project
// 2003 Jan 31: Cleaned up some unused imports.
//
// 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 <license@opennms.org>
// http://www.opennms.org/
// http://www.opennms.com/
//
// Tab Size = 8
//
package org.infosec.ismp.poller;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.infosec.ismp.eventd.EventIpcManager;
import org.infosec.ismp.model.event.Event;
import org.infosec.ismp.model.event.EventConstants;
import org.infosec.ismp.model.event.EventListener;
import org.infosec.ismp.model.event.EventUtils;
import org.infosec.ismp.poller.pollable.PollableInterface;
import org.infosec.ismp.poller.pollable.PollableNetwork;
import org.infosec.ismp.poller.pollable.PollableNode;
import org.infosec.ismp.poller.pollable.PollableService;
import org.infosec.ismp.util.ThreadCategory;
/**
*
*/
final class PollerEventProcessor implements EventListener {
private final Poller m_poller;
private volatile DemandPollDao m_demandPollDao;
/**
* Create message selector to set to the subscription
*/
private void createMessageSelectorAndSubscribe() {
// Create the selector for the UEIs this service is interested in
//
List<String> ueiList = new ArrayList<String>();
// nodeGainedService
ueiList.add(EventConstants.NODE_GAINED_SERVICE_EVENT_UEI);
// serviceDeleted
// deleteService
/*
* NOTE: deleteService is only generated by the PollableService itself.
* Therefore, we ignore it. If future implementations allow other
* subsystems to generate this event, we may have to listen for it as
* well. 'serviceDeleted' is the response event that the outage manager
* generates. We ignore this as well, since the PollableService has
* already taken action at the time it generated 'deleteService'
*/
ueiList.add(EventConstants.SERVICE_DELETED_EVENT_UEI);
// ueiList.add(EventConstants.DELETE_SERVICE_EVENT_UEI);
// serviceManaged
// serviceUnmanaged
// interfaceManaged
// interfaceUnmanaged
/*
* NOTE: These are all ignored because the responsibility is currently
* on the class generating the event to restart the poller service. If
* that implementation is ever changed, this message selector should
* listen for these and act on them.
*/
// ueiList.add(EventConstants.SERVICE_MANAGED_EVENT_UEI);
// ueiList.add(EventConstants.SERVICE_UNMANAGED_EVENT_UEI);
// ueiList.add(EventConstants.INTERFACE_MANAGED_EVENT_UEI);
// ueiList.add(EventConstants.INTERFACE_UNMANAGED_EVENT_UEI);
// interfaceIndexChanged
// NOTE: No longer interested in this event...if Capsd detects
// that in interface's index has changed a
// 'reinitializePrimarySnmpInterface' event is generated.
// ueiList.add(EventConstants.INTERFACE_INDEX_CHANGED_EVENT_UEI);
// interfaceReparented
ueiList.add(EventConstants.INTERFACE_REPARENTED_EVENT_UEI);
// reloadPollerConfig
/*
* NOTE: This is ignored because the reload is handled through an
* autoaction.
*/
// ueiList.add(EventConstants.RELOAD_POLLER_CONFIG_EVENT_UEI);
// NODE OUTAGE RELATED EVENTS
//
// nodeAdded
/*
* NOTE: This is ignored. The real trigger will be the first
* nodeGainedService event, at which time the interface and node will be
* created
*/
// ueiList.add(EventConstants.NODE_ADDED_EVENT_UEI);
// nodeDeleted
ueiList.add(EventConstants.NODE_DELETED_EVENT_UEI);
// duplicateNodeDeleted
ueiList.add(EventConstants.DUP_NODE_DELETED_EVENT_UEI);
// nodeGainedInterface
/*
* NOTE: This is ignored. The real trigger will be the first
* nodeGainedService event, at which time the interface and node will be
* created
*/
// ueiList.add(EventConstants.NODE_GAINED_INTERFACE_EVENT_UEI);
// interfaceDeleted
ueiList.add(EventConstants.INTERFACE_DELETED_EVENT_UEI);
// suspendPollingService
ueiList.add(EventConstants.SUSPEND_POLLING_SERVICE_EVENT_UEI);
// resumePollingService
ueiList.add(EventConstants.RESUME_POLLING_SERVICE_EVENT_UEI);
// scheduled outage configuration change
ueiList.add(EventConstants.SCHEDOUTAGES_CHANGED_EVENT_UEI);
// demand poll
ueiList.add(EventConstants.DEMAND_POLL_SERVICE_EVENT_UEI);
// update threshold configuration
ueiList.add(EventConstants.THRESHOLDCONFIG_CHANGED_EVENT_UEI);
// Subscribe to eventd
getEventManager().addEventListener(this, ueiList);
}
/**
* 处理新增轮询服务事件
* @param event
* The event to process.
*
*/
private void nodeGainedServiceHandler(Event event) {
ThreadCategory log = ThreadCategory.getInstance(getClass());
// Is this the result of a resumePollingService event?
@SuppressWarnings("unused")
String whichEvent = "Unexpected Event: " + event.getUei() + ": ";
if (event.getUei().equals(EventConstants.NODE_GAINED_SERVICE_EVENT_UEI)) {
whichEvent = "nodeGainedService: ";
} else if (event.getUei().equals(
EventConstants.RESUME_POLLING_SERVICE_EVENT_UEI)) {
whichEvent = "resumePollingService: ";
}
// First make sure the service gained is in active state before trying
// to schedule
String ipAddr = event.getNetInterface();
int nodeId = (int) event.getNodeid();
String svcName = event.getService();
String nodeLabel = EventUtils.getParm(event,
EventConstants.PARM_NODE_LABEL);
try {
nodeLabel = getPoller().getQueryManager().getNodeLabel(nodeId);
} catch (Exception e) {
log.error("Unable to retrieve nodeLabel for node " + nodeId, e);
}
getPoller().scheduleService(nodeId, nodeLabel, ipAddr, svcName);
}
/**
* This method is responsible for processing 'interfacReparented' events. An
* 'interfaceReparented' event will have old and new nodeId parms associated
* with it. Node outage processing hierarchy will be updated to reflect the
* new associations.
*
* @param event
* The event to process.
*
*/
private void interfaceReparentedHandler(Event event) {
ThreadCategory log = ThreadCategory.getInstance(getClass());
if (log.isDebugEnabled())
log.debug("interfaceReparentedHandler: processing interfaceReparented event for "
+ event.getInterface());
// Verify that the event has an interface associated with it
if (event.getInterface() == null)
return;
String ipAddr = event.getInterface();
// Extract the old and new nodeId's from the event parms
String oldNodeIdStr = null;
String newNodeIdStr = null;
Parms parms = event.getParms();
if (parms != null) {
String parmName = null;
Value parmValue = null;
String parmContent = null;
for (Parm parm : parms.getParmCollection()) {
parmName = parm.getParmName();
parmValue = parm.getValue();
if (parmValue == null)
continue;
else
parmContent = parmValue.getContent();
// old nodeid
if (parmName.equals(EventConstants.PARM_OLD_NODEID)) {
oldNodeIdStr = parmContent;
}
// new nodeid
else if (parmName.equals(EventConstants.PARM_NEW_NODEID)) {
newNodeIdStr = parmContent;
}
}
}
// Only proceed provided we have both an old and a new nodeId
//
if (oldNodeIdStr == null || newNodeIdStr == null) {
log.error("interfaceReparentedHandler: old and new nodeId parms are required, unable to process.");
return;
}
PollableNode oldNode;
PollableNode newNode;
try {
oldNode = getNetwork().getNode(Integer.parseInt(oldNodeIdStr));
if (oldNode == null) {
log.error("interfaceReparentedHandler: Cannot locate old node "
+ oldNodeIdStr + " belonging to interface " + ipAddr);
return;
}
newNode = getNetwork().getNode(Integer.parseInt(newNodeIdStr));
if (newNode == null) {
log.error("interfaceReparentedHandler: Cannot locate new node "
+ newNodeIdStr + " to move interface to.");
return;
}
PollableInterface iface = oldNode.getInterface(InetAddress
.getByName(ipAddr));
if (iface == null) {
log.error("interfaceReparentedHandler: Cannot locate interface with ipAddr "
+ ipAddr + " to reparent.");
return;
}
iface.reparentTo(newNode);
} catch (NumberFormatException nfe) {
log.error("interfaceReparentedHandler: failed converting old/new nodeid parm to integer, unable to process.");
return;
} catch (UnknownHostException e) {
log.error("interfaceReparentedHandler: failed converting ipAddr "
+ ipAddr + " to an inet address");
return;
}
}
/**
* This method is responsible for removing a node's pollable service from
* the pollable services list
*/
private void nodeRemovePollableServiceHandler(Event event) {
ThreadCategory log = ThreadCategory.getInstance(getClass());
int nodeId = (int) event.getNodeid();
String ipAddr = event.getInterface();
String svcName = event.getService();
InetAddress address;
try {
address = InetAddress.getByName(ipAddr);
} catch (UnknownHostException e) {
log.error("Unable to convert " + ipAddr + " to an inet address", e);
return;
}
if (svcName == null) {
log.error("nodeRemovePollableServiceHandler: service name is null, ignoring event");
return;
}
PollableService svc = getNetwork().getService(nodeId, address, svcName);
svc.delete();
}
/**
*管理节点(服务器)被删除
*/
private void nodeDeletedHandler(Event event) {
ThreadCategory log = ThreadCategory.getInstance(getClass());
int nodeId = (int) event.getNodeid();
final String sourceUei = event.getUei();
// Extract node label and transaction No. from the event parms
long txNo = -1L;
Parms parms = event.getParms();
if (parms != null) {
String parmName = null;
Value parmValue = null;
String parmContent = null;
for (Parm parm : parms.getParmCollection()) {
parmName = parm.getParmName();
parmValue = parm.getValue();
if (parmValue == null)
continue;
else
parmContent = parmValue.getContent();
// get the external transaction number
if (parmName.equals(EventConstants.PARM_TRANSACTION_NO)) {
String temp = parmContent;
if (log.isDebugEnabled())
log.debug("nodeDeletedHandler: parmName: " + parmName
+ " /parmContent: " + parmContent);
try {
txNo = Long.valueOf(temp).longValue();
} catch (NumberFormatException nfe) {
log.warn("nodeDeletedHandler: Parameter "
+ EventConstants.PARM_TRANSACTION_NO
+ " cannot be non-numberic", nfe);
txNo = -1;
}
}
}
}
Date closeDate;
try {
closeDate = event.getTime();
} catch (ParseException e) {
closeDate = new Date();
}
getPoller().closeOutagesForNode(closeDate, event.getDbid(), nodeId);
PollableNode node = getNetwork().getNode(nodeId);
if (node == null) {
log.error("Nodeid "
+ nodeId
+ " does not exist in pollable node map, unable to delete node.");
if (isXmlRPCEnabled()) {
int status = EventConstants.XMLRPC_NOTIFY_FAILURE;
XmlrpcUtil.createAndSendXmlrpcNotificationEvent(txNo,
sourceUei, "Node does not exist in pollable node map.",
status, "OpenNMS.Poller");
}
return;
}
node.delete();
}
/**
*
*/
private void interfaceDeletedHandler(Event event) {
ThreadCategory log = ThreadCategory.getInstance(getClass());
int nodeId = (int) event.getNodeid();
String sourceUei = event.getUei();
String ipAddr = event.getInterface();
// Extract node label and transaction No. from the event parms
long txNo = -1L;
Parms parms = event.getParms();
if (parms != null) {
String parmName = null;
Value parmValue = null;
String parmContent = null;
for (Parm parm : parms.getParmCollection()) {
parmName = parm.getParmName();
parmValue = parm.getValue();
if (parmValue == null)
continue;
else
parmContent = parmValue.getContent();
// get the external transaction number
if (parmName.equals(EventConstants.PARM_TRANSACTION_NO)) {
String temp = parmContent;
if (log.isDebugEnabled())
log.debug("interfaceDeletedHandlerHandler: parmName: "
+ parmName + " /parmContent: " + parmContent);
try {
txNo = Long.valueOf(temp).longValue();
} catch (NumberFormatException nfe) {
log.warn("interfaceDeletedHandlerHandler: Parameter "
+ EventConstants.PARM_TRANSACTION_NO
+ " cannot be non-numberic", nfe);
txNo = -1;
}
}
}
}
InetAddress addr;
try {
addr = InetAddress.getByName(ipAddr);
} catch (UnknownHostException e) {
log.error("interfaceDeletedHandler: Could not convert interface "
+ event.getInterface() + " to InetAddress", e);
return;
}
Date closeDate;
try {
closeDate = EventConstants.parseToDate(event.getTime());
} catch (ParseException e) {
closeDate = new Date();
}
getPoller().closeOutagesForInterface(closeDate, event.getDbid(),
nodeId, ipAddr);
PollableInterface iface = getNetwork().getInterface(nodeId, addr);
if (iface == null) {
log.error("Interface "
+ nodeId
+ "/"
+ event.getInterface()
+ " does not exist in pollable node map, unable to delete node.");
if (isXmlRPCEnabled()) {
int status = EventConstants.XMLRPC_NOTIFY_FAILURE;
XmlrpcUtil.createAndSendXmlrpcNotificationEvent(txNo,
sourceUei,
"Interface does not exist in pollable node map.",
status, "OpenNMS.Poller");
}
return;
}
iface.delete();
}
/**
* <p>
* This method remove a deleted service from the pollable service list of
* the specified interface, so that it will not be scheduled by the poller.
* </p>
*/
private void serviceDeletedHandler(Event event) {
ThreadCategory log = ThreadCategory.getInstance(getClass());
int nodeId = (int) event.getNodeid();
String ipAddr = event.getInterface();
String service = event.getService();
InetAddress addr;
try {
addr = InetAddress.getByName(ipAddr);
} catch (UnknownHostException e) {
log.error("serviceDeletedHandler: Could not convert " + ipAddr
+ " to an InetAddress", e);
return;
}
Date closeDate;
try {
closeDate = EventConstants.parseToDate(event.getTime());
} catch (ParseException e) {
closeDate = new Date();
}
getPoller().closeOutagesForService(closeDate, event.getDbid(), nodeId,
ipAddr, service);
PollableService svc = getNetwork().getService(nodeId, addr, service);
if (svc == null) {
log.error("Interface "
+ nodeId
+ "/"
+ event.getInterface()
+ " does not exist in pollable node map, unable to delete node.");
return;
}
svc.delete();
}
/**
* Constructor
*
* @param pollableServices
* List of all the PollableService objects scheduled for polling
*/
PollerEventProcessor(Poller poller) {
m_poller = poller;
createMessageSelectorAndSubscribe();
ThreadCategory log = ThreadCategory.getInstance(getClass());
if (log.isDebugEnabled())
log.debug("Subscribed to eventd");
}
/**
* Unsubscribe from eventd
*/
public void close() {
getEventManager().removeEventListener(this);
}
/**
* @return
*/
private EventIpcManager getEventManager() {
return getPoller().getEventManager();
}
/**
* This method is invoked by the EventIpcManager when a new event is
* available for processing. Each message is examined for its Universal
* Event Identifier and the appropriate action is taking based on each UEI.
*
* @param event
* The event
*/
@Override
public void onEvent(Event event) {
if (event == null)
return;
ThreadCategory log = ThreadCategory.getInstance(getClass());
// print out the uei
//
if (log.isDebugEnabled()) {
log.debug("PollerEventProcessor: received event, uei = "
+ event.getUei());
}
if (event.getUei()
.equals(EventConstants.SCHEDOUTAGES_CHANGED_EVENT_UEI)) {
log.info("Reloading poller config factory and polloutages config factory");
scheduledOutagesChangeHandler(log);
} else if (event.getUei().equals(
EventConstants.THRESHOLDCONFIG_CHANGED_EVENT_UEI)) {
log.info("Reloading thresholding configuration in pollerd");
thresholdsConfigChangeHandler(log);
} else if (!event.hasNodeid()) {
// For all other events, if the event doesn't have a nodeId it can't
// be processed.
log.info("PollerEventProcessor: no database node id found, discarding event");
} else if (event.getUei().equals(
EventConstants.NODE_GAINED_SERVICE_EVENT_UEI)) {
// If there is no interface then it cannot be processed
//
if (event.getNetInterface() == null
|| event.getNetInterface().length() == 0) {
log.info("PollerEventProcessor: no interface found, discarding event");
} else {
nodeGainedServiceHandler(event);
}
} else if (event.getUei().equals(
EventConstants.RESUME_POLLING_SERVICE_EVENT_UEI)) {
// If there is no interface then it cannot be processed
//
if (event.getNetInterface() == null
|| event.getNetInterface().length() == 0) {
log.info("PollerEventProcessor: no interface found, cannot resume polling service, discarding event");
} else {
nodeGainedServiceHandler(event);
}
} else if (event.getUei().equals(
EventConstants.SUSPEND_POLLING_SERVICE_EVENT_UEI)) {
// If there is no interface then it cannot be processed
//
if (event.getNetInterface() == null
|| event.getNetInterface().length() == 0) {
log.info("PollerEventProcessor: no interface found, cannot suspend polling service, discarding event");
} else {
nodeRemovePollableServiceHandler(event);
}
} else if (event.getUei().equals(
EventConstants.INTERFACE_REPARENTED_EVENT_UEI)) {
// If there is no interface then it cannot be processed
//
if (event.getNetInterface() == null
|| event.getNetInterface().length() == 0) {
log.info("PollerEventProcessor: no interface found, discarding event");
} else {
interfaceReparentedHandler(event);
}
} else if (event.getUei().equals(EventConstants.NODE_DELETED_EVENT_UEI)
|| event.getUei().equals(
EventConstants.DUP_NODE_DELETED_EVENT_UEI)) {
if (event.getNodeid() < 0) {
log.info("PollerEventProcessor: no node or interface found, discarding event");
}
// NEW NODE OUTAGE EVENTS
nodeDeletedHandler(event);
} else if (event.getUei().equals(
EventConstants.INTERFACE_DELETED_EVENT_UEI)) {
// If there is no interface then it cannot be processed
//
if (event.getNodeid() < 0 || event.getInterface() == null
|| event.getInterface().length() == 0) {
log.info("PollerEventProcessor: invalid nodeid or no interface found, discarding event");
} else {
interfaceDeletedHandler(event);
}
} else if (event.getUei().equals(
EventConstants.SERVICE_DELETED_EVENT_UEI)) {
// If there is no interface then it cannot be processed
//
if ((event.getNodeid() < 0) || (event.getInterface() == null)
|| (event.getInterface().length() == 0)
|| (event.getService() == null)) {
log.info("PollerEventProcessor: invalid nodeid or no nodeinterface "
+ "or service found, discarding event");
} else {
serviceDeletedHandler(event);
}
} // end single event process
} // end onEvent()
@SuppressWarnings("unused")
private void demandPollServiceHandler(Event e) {
// EventUtils.checkNodeId(e);
// EventUtils.checkInterface(e);
// EventUtils.checkService(e);
// EventUtils.requireParm(e, EventConstants.PARM_DEMAND_POLL_ID);
// m_demandPollDao.get(EventUtils.getIntParm(e,
// EventConstants.PARM_DEMAND_POLL_ID, -1));
}
private void scheduledOutagesChangeHandler(ThreadCategory log) {
try {
getPollerConfig().update();
getPoller().getPollOutagesConfig().update();
} catch (Exception e) {
e.printStackTrace();
log.error(
"Failed to reload PollerConfigFactory because "
+ e.getMessage(), e);
}
// getPoller().refreshServicePackages();
}
private void thresholdsConfigChangeHandler(ThreadCategory log) {
// getPoller().refreshServiceThresholds();
}
/**
* Return an id for this event listener
*/
@Override
public String getName() {
return "Poller:PollerEventProcessor";
}
/**
* @return
*/
private Poller getPoller() {
return m_poller;
}
/**
* @return
*/
private PollerConfig getPollerConfig() {
return getPoller().getPollerConfig();
}
private PollableNetwork getNetwork() {
return getPoller().getNetwork();
}
} // end class