/***********************************************************************************
*
* Copyright (c) 2015 Kamil Baczkowicz
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* The Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
*
* Kamil Baczkowicz - initial API and implementation and/or initial documentation
*
*/
package pl.baczkowicz.mqttspy.daemon;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pl.baczkowicz.mqttspy.common.generated.ReconnectionSettings;
import pl.baczkowicz.mqttspy.connectivity.SimpleMqttConnection;
import pl.baczkowicz.mqttspy.connectivity.reconnection.ReconnectionManager;
import pl.baczkowicz.mqttspy.daemon.configuration.MqttSpyDaemonConfigLoader;
import pl.baczkowicz.mqttspy.daemon.configuration.generated.DaemonMqttConnectionDetails;
import pl.baczkowicz.mqttspy.daemon.configuration.generated.MqttSpyDaemonConfiguration;
import pl.baczkowicz.mqttspy.daemon.connectivity.MqttCallbackHandler;
import pl.baczkowicz.mqttspy.daemon.connectivity.SimpleMqttConnectionRunnable;
import pl.baczkowicz.mqttspy.scripts.MqttScriptIO;
import pl.baczkowicz.mqttspy.scripts.MqttScriptManager;
import pl.baczkowicz.spy.configuration.BasePropertyNames;
import pl.baczkowicz.spy.daemon.BaseDaemon;
import pl.baczkowicz.spy.eventbus.IKBus;
import pl.baczkowicz.spy.eventbus.KBus;
import pl.baczkowicz.spy.exceptions.SpyException;
import pl.baczkowicz.spy.exceptions.XMLException;
import pl.baczkowicz.spy.testcases.TestCaseManager;
/**
* The main class of the daemon.
*/
public class MqttSpyDaemon extends BaseDaemon
{
/** Diagnostic logger. */
private final static Logger logger = LoggerFactory.getLogger(MqttSpyDaemon.class);
private MqttSpyDaemonConfigLoader loader;
private ReconnectionManager mqttReconnectionManager;
protected SimpleMqttConnection mqttConnection;
private MqttCallbackHandler mqttCallback;
private MqttScriptIO scriptIO;
/**
* This is an internal method - initialises the daemon class.
*
* @throws XMLException Thrown if cannot instantiate itself
*/
public void initialise() throws XMLException
{
loader = new MqttSpyDaemonConfigLoader();
showInfo();
}
protected void showInfo()
{
logger.info("#######################################################");
logger.info("### Starting mqtt-spy-daemon v{}", loader.getFullVersionName());
logger.info("### If you find it useful, see how you can help at {}", loader.getProperty(BasePropertyNames.DOWNLOAD_URL));
logger.info("### To get release updates follow @mqtt_spy on Twitter ");
logger.info("#######################################################");
}
/**
* This is an internal method - requires "initialise" to be called first.
*
* @param configurationFile Location of the configuration file
* @throws SpyException Thrown if cannot initialise
*/
public void loadAndRun(final String configurationFile) throws SpyException
{
// Load the configuration
// loader.loadConfiguration(new File(configurationFile));
loader.loadConfiguration(configurationFile);
loadAndRun(loader.getConfiguration());
}
/**
* This is an internal method - requires "initialise" to be called first.
*
* @param configuration Configuration object
* @throws SpyException Thrown if cannot initialise
*/
protected void loadAndRun(final MqttSpyDaemonConfiguration configuration) throws SpyException
{
// Retrieve connection details
final DaemonMqttConnectionDetails connectionSettings = configuration.getConnection();
configureMqtt(connectionSettings);
runScripts(connectionSettings.getBackgroundScript(), connectionSettings.getTestCases(), connectionSettings.getRunningMode());
}
protected void configureMqtt(final DaemonMqttConnectionDetails connectionSettings) throws SpyException
{
final IKBus eventBus = new KBus();
// Wire up all classes (assuming ID = 0)
mqttReconnectionManager = new ReconnectionManager();
mqttConnection = new SimpleMqttConnection(mqttReconnectionManager, "0", connectionSettings);
scriptManager = new MqttScriptManager(eventBus, null, mqttConnection);
testCaseManager = new TestCaseManager(scriptManager);
mqttCallback = new MqttCallbackHandler(mqttConnection, connectionSettings, scriptManager);
// Set up reconnection
final ReconnectionSettings reconnectionSettings = mqttConnection.getMqttConnectionDetails().getReconnectionSettings();
final Runnable connectionRunnable = new SimpleMqttConnectionRunnable(scriptManager, mqttConnection, connectionSettings);
mqttConnection.setScriptManager(scriptManager);
mqttConnection.connect(mqttCallback, connectionRunnable);
scriptIO = new MqttScriptIO(mqttConnection, eventBus, null, null);
if (reconnectionSettings != null)
{
new Thread(mqttReconnectionManager).start();
}
}
public boolean canPublish()
{
return mqttConnection.canPublish();
}
/**
* Tries to stop all running threads (apart from scripts) and close the connection.
*/
protected void waitAndStop()
{
waitForScripts();
stopMqtt();
displayGoodbyeMessage();
}
protected void stopMqtt()
{
// Stop reconnection manager
if (mqttReconnectionManager != null)
{
mqttReconnectionManager.stop();
}
// Disconnect
mqttConnection.disconnect();
// Stop message logger
mqttCallback.stop();
}
/**
* This exposes additional methods, e.g. publish, subscribe, unsubscribe.
*
* @return The Script IO with the extra methods
*/
public MqttScriptIO more()
{
return scriptIO;
}
}