/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 2008-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.daemon; import org.opennms.core.utils.ThreadCategory; import org.opennms.netmgt.model.ServiceDaemon; /** * <p>Abstract AbstractServiceDaemon class.</p> * * @author <a href="mailto:brozow@opennms.org">Mathew Brozowski</a> * @author <a href="mailto:dj@opennms.org">DJ Gregor</a> */ public abstract class AbstractServiceDaemon implements ServiceDaemon, SpringServiceDaemon { /** * <p>afterPropertiesSet</p> * * @throws java.lang.Exception if any. */ @Override public final void afterPropertiesSet() throws Exception { init(); } /** * The current status of this fiber */ private int m_status; private String m_name; private Object m_statusLock = new Object(); /** * <p>onInit</p> */ abstract protected void onInit(); /** * <p>onPause</p> */ protected void onPause() {} /** * <p>onResume</p> */ protected void onResume() {} /** * <p>onStart</p> */ protected void onStart() {} /** * <p>onStop</p> */ protected void onStop() {} /** * <p>getName</p> * * @return a {@link java.lang.String} object. */ @Override final public String getName() { return m_name; } /** * <p>Constructor for AbstractServiceDaemon.</p> * * @param name a {@link java.lang.String} object. */ protected AbstractServiceDaemon(final String name) { m_name = name; setStatus(START_PENDING); } /** * <p>setStatus</p> * * @param status a int. */ protected final void setStatus(final int status) { synchronized (m_statusLock) { m_status = status; m_statusLock.notifyAll(); } } /** * <p>waitForStatus</p> * * @param status a int. * @param timeout a long. * @throws java.lang.InterruptedException if any. */ protected final void waitForStatus(final int status, final long timeout) throws InterruptedException { synchronized (m_statusLock) { final long last = System.currentTimeMillis(); long waitTime = timeout; while (status != m_status && waitTime > 0) { m_statusLock.wait(waitTime); long now = System.currentTimeMillis(); waitTime -= (now - last); } } } /** * <p>waitForStatus</p> * * @param status a int. * @throws java.lang.InterruptedException if any. */ protected final void waitForStatus(final int status) throws InterruptedException { synchronized (m_statusLock) { while (status != m_status) { m_statusLock.wait(); } } } /** * <p>getStatus</p> * * @return a int. */ @Override public int getStatus() { synchronized (m_statusLock) { return m_status; } } /** * <p>getStatusText</p> * * @return a {@link java.lang.String} object. */ @Override public String getStatusText() { return STATUS_NAMES[getStatus()]; } /** * <p>status</p> * * @return a {@link java.lang.String} object. * * @deprecated Use {@link #getStatusText()} instead. This field is only for * backwards compatibility with JMX operations. */ public String status() { return getStatusText(); } /** * <p>isRunning</p> * * @return a boolean. */ protected synchronized boolean isRunning() { return getStatus() == RUNNING; } /** * <p>isPaused</p> * * @return a boolean. */ protected synchronized boolean isPaused() { return getStatus() == PAUSED; } /** * <p>isStarting</p> * * @return a boolean. */ protected synchronized boolean isStarting() { return getStatus() == STARTING; } /** * <p>log</p> * * @return a {@link org.opennms.core.utils.ThreadCategory} object. */ protected ThreadCategory log() { return ThreadCategory.getInstance(getClass()); } /** * <p>fatalf</p> * * @param format a {@link java.lang.String} object. * @param args a {@link java.lang.Object} object. */ protected void fatalf(final String format, final Object... args) { log().fatal(String.format(format, args)); } /** * <p>fatalf</p> * * @param t a {@link java.lang.Throwable} object. * @param format a {@link java.lang.String} object. * @param args a {@link java.lang.Object} object. */ protected void fatalf(final Throwable t, final String format, final Object... args) { log().fatal(String.format(format, args), t); } /** * <p>errorf</p> * * @param format a {@link java.lang.String} object. * @param args a {@link java.lang.Object} object. */ protected void errorf(final String format, final Object... args) { log().error(String.format(format, args)); } /** * <p>errorf</p> * * @param t a {@link java.lang.Throwable} object. * @param format a {@link java.lang.String} object. * @param args a {@link java.lang.Object} object. */ protected void errorf(final Throwable t, final String format, final Object... args) { log().error(String.format(format, args), t); } /** * <p>warnf</p> * * @param format a {@link java.lang.String} object. * @param args a {@link java.lang.Object} object. */ protected void warnf(final String format, final Object... args) { log().warn(String.format(format, args)); } /** * <p>warnf</p> * * @param t a {@link java.lang.Throwable} object. * @param format a {@link java.lang.String} object. * @param args a {@link java.lang.Object} object. */ protected void warnf(final Throwable t, final String format, final Object... args) { log().warn(String.format(format, args), t); } /** * <p>infof</p> * * @param format a {@link java.lang.String} object. * @param args a {@link java.lang.Object} object. */ protected void infof(final String format, final Object... args) { if (log().isInfoEnabled()) { log().info(String.format(format, args)); } } /** * <p>infof</p> * * @param t a {@link java.lang.Throwable} object. * @param format a {@link java.lang.String} object. * @param args a {@link java.lang.Object} object. */ protected void infof(final Throwable t, final String format, final Object... args) { if (log().isInfoEnabled()) { log().info(String.format(format, args), t); } } /** * <p>debugf</p> * * @param format a {@link java.lang.String} object. * @param args a {@link java.lang.Object} object. */ protected void debugf(final String format, final Object... args) { if (log().isDebugEnabled()) { log().debug(String.format(format, args)); } } /** * <p>debugf</p> * * @param t a {@link java.lang.Throwable} object. * @param format a {@link java.lang.String} object. * @param args a {@link java.lang.Object} object. */ protected void debugf(final Throwable t, final String format, final Object... args) { if (log().isDebugEnabled()) { log().debug(String.format(format, args), t); } } /** * <p>init</p> */ final public void init() { final String prefix = ThreadCategory.getPrefix(); try { ThreadCategory.setPrefix(getName()); log().info(getName()+" initializing."); onInit(); log().info(getName()+" initialization complete."); } finally { ThreadCategory.setPrefix(prefix); } } /** * <p>pause</p> */ @Override final public void pause() { final String prefix = ThreadCategory.getPrefix(); try { ThreadCategory.setPrefix(getName()); if (!isRunning()) return; log().info(getName()+" pausing."); setStatus(PAUSE_PENDING); onPause(); setStatus(PAUSED); log().info(getName()+" paused."); } finally { ThreadCategory.setPrefix(prefix); } } /** * <p>resume</p> */ @Override final public void resume() { final String prefix = ThreadCategory.getPrefix(); try { ThreadCategory.setPrefix(getName()); if (!isPaused()) return; log().info(getName()+" resuming."); setStatus(RESUME_PENDING); onResume(); setStatus(RUNNING); log().info(getName()+" resumed."); } finally { ThreadCategory.setPrefix(prefix); } } /** * <p>start</p> */ @Override final public synchronized void start() { final String prefix = ThreadCategory.getPrefix(); try { ThreadCategory.setPrefix(getName()); log().info(getName()+" starting."); setStatus(STARTING); onStart(); setStatus(RUNNING); log().info(getName()+" started."); } finally { ThreadCategory.setPrefix(prefix); } } /** * Stops the currently running service. If the service is not running then * the command is silently discarded. */ @Override final public synchronized void stop() { final String prefix = ThreadCategory.getPrefix(); try { ThreadCategory.setPrefix(getName()); log().info(getName()+" stopping."); setStatus(STOP_PENDING); onStop(); setStatus(STOPPED); log().info(getName()+" stopped."); } finally { ThreadCategory.setPrefix(prefix); } } /** * Destroys the current service. */ @Override final public void destroy() { stop(); } }