/******************************************************************************* * 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.alarmd.api.support; import java.util.List; import org.opennms.netmgt.alarmd.api.NorthboundAlarm; import org.opennms.netmgt.alarmd.api.Northbounder; import org.opennms.netmgt.alarmd.api.NorthbounderException; /** * AbstractNorthBounder * * The purpose of this class is manage the queue of alarms that need to be forward and receive queries to/from a Southbound Interface. * * It passes Alarms on to the forwardAlarms method implemented by base classes in batches as they are * added to the queue. The forwardAlarms method does the actual work of sending them to the Southbound Interface. * * preserve, accept and discard are called to add the Alarms to the queue as appropriate. * * @author <a mailto:david@opennms.org>David Hustace</a> */ public abstract class AbstractNorthbounder implements Northbounder, Runnable, StatusFactory<NorthboundAlarm> { private final String m_name; private final AlarmQueue<NorthboundAlarm> m_queue; private Thread m_thread; private volatile boolean m_stopped = true; private long m_retryInterval = 1000; protected AbstractNorthbounder(String name) { m_name = name; m_queue = new AlarmQueue<NorthboundAlarm>(this); } public String getName() { return m_name; } public void setNaglesDelay (long delay) { m_queue.setNaglesDelay(delay); } public void setRetryInterval(int retryInterval) { m_retryInterval = retryInterval; } public void setMaxBatchSize(int maxBatchSize) { m_queue.setMaxBatchSize(maxBatchSize); } public void setMaxPreservedAlarms(int maxPreservedAlarms) { m_queue.setMaxPreservedAlarms(maxPreservedAlarms); } /** Override this to perform actions before startup. **/ protected void onPreStart() {} /** Override this to perform actions after startup. **/ protected void onPostStart() {} @Override public final void start() throws NorthbounderException { if (! m_stopped) return; this.onPreStart(); m_stopped = false; m_queue.init(); m_thread = new Thread(this, getName()+"-Thread"); m_thread.start(); this.onPostStart(); } @Override public final void onAlarm(NorthboundAlarm alarm) throws NorthbounderException { if (accepts(alarm)) { m_queue.accept(alarm); } }; protected abstract boolean accepts(NorthboundAlarm alarm); protected void preserve(NorthboundAlarm alarm) throws NorthbounderException { m_queue.preserve(alarm); } protected void discard(NorthboundAlarm alarm) throws NorthbounderException { m_queue.discard(alarm); } /** Override this to perform actions when stopping. **/ protected void onStop() { } public final void stop() throws NorthbounderException { this.onStop(); m_stopped = true; } public void run() { try { while(!m_stopped) { List<NorthboundAlarm> alarmsToForward = m_queue.getAlarmsToForward(); try { forwardAlarms(alarmsToForward); m_queue.forwardSuccessful(alarmsToForward); } catch (Exception e) { m_queue.forwardFailed(alarmsToForward); if (!m_stopped) { // a failure occurred so sleep a moment and try again Thread.sleep(m_retryInterval); } } } } catch (InterruptedException e) { // thread interrupted so complete it } } @Override public NorthboundAlarm createSyncLostMessage() { return NorthboundAlarm.SYNC_LOST_ALARM; } public abstract void forwardAlarms(List<NorthboundAlarm> alarms) throws NorthbounderException; }