From 30eeb29b4b353929bc9469dac70c9e18da3f1f75 Mon Sep 17 00:00:00 2001 From: maroy Date: Sun, 25 Jul 2004 15:41:19 +0000 Subject: [PATCH] added global test case for testing the uploadPlaylist function through the XML-RPC interface --- .../LiveSupport/Db/ConnectionManagerFactory.h | 6 +- .../modules/storage/etc/storageClient.xml | 2 +- .../modules/storage/etc/testResultToHtml.xsl | 63 ++++++++ .../Storage/StorageClientFactory.h | 30 +++- .../products/scheduler/etc/Makefile.in | 26 +++- .../products/scheduler/etc/configure.ac | 5 +- .../products/scheduler/etc/doxygen.config | 4 +- .../products/scheduler/etc/scheduler.xml | 40 +++++- .../scheduler/src/PostgresqlSchedule.h | 17 ++- .../scheduler/src/ScheduleFactory.cxx | 29 +++- .../products/scheduler/src/ScheduleFactory.h | 55 ++++++- .../scheduler/src/SchedulerDaemon.cxx | 85 ++++++++++- .../products/scheduler/src/SchedulerDaemon.h | 92 ++++++++++-- .../scheduler/src/SchedulerDaemonTest.cxx | 12 +- .../src/SchedulerDaemonUploadTest.cxx | 135 ++++++++++++++++++ .../scheduler/src/SchedulerDaemonUploadTest.h | 108 ++++++++++++++ .../scheduler/src/UploadPlaylistMethod.cxx | 24 ++-- .../scheduler/src/UploadPlaylistMethod.h | 17 ++- .../src/UploadPlaylistMethodTest.cxx | 29 ++-- .../products/scheduler/src/XmlRpcDaemon.cxx | 85 ++++++++--- .../products/scheduler/src/XmlRpcDaemon.h | 40 ++++-- livesupport/products/scheduler/src/main.cxx | 23 ++- 22 files changed, 828 insertions(+), 99 deletions(-) create mode 100644 livesupport/modules/storage/etc/testResultToHtml.xsl create mode 100644 livesupport/products/scheduler/src/SchedulerDaemonUploadTest.cxx create mode 100644 livesupport/products/scheduler/src/SchedulerDaemonUploadTest.h diff --git a/livesupport/modules/db/include/LiveSupport/Db/ConnectionManagerFactory.h b/livesupport/modules/db/include/LiveSupport/Db/ConnectionManagerFactory.h index 19b4ae3d6..ace48382a 100644 --- a/livesupport/modules/db/include/LiveSupport/Db/ConnectionManagerFactory.h +++ b/livesupport/modules/db/include/LiveSupport/Db/ConnectionManagerFactory.h @@ -22,7 +22,7 @@ Author : $Author: maroy $ - Version : $Revision: 1.1 $ + Version : $Revision: 1.2 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/db/include/LiveSupport/Db/ConnectionManagerFactory.h,v $ ------------------------------------------------------------------------------*/ @@ -90,7 +90,7 @@ using namespace LiveSupport::Core; * element, see the SimpleConnectionManager documentation. * * @author $Author: maroy $ - * @version $Revision: 1.1 $ + * @version $Revision: 1.2 $ * @see SimpleConnectionManager */ class ConnectionManagerFactory : @@ -136,7 +136,7 @@ class ConnectionManagerFactory : * @return the name of the expected XML configuration element. */ static const std::string - configElementName(void) throw () + getConfigElementName(void) throw () { return configElementNameStr; } diff --git a/livesupport/modules/storage/etc/storageClient.xml b/livesupport/modules/storage/etc/storageClient.xml index dcb178943..fa5b4a8f0 100644 --- a/livesupport/modules/storage/etc/storageClient.xml +++ b/livesupport/modules/storage/etc/storageClient.xml @@ -1,7 +1,7 @@ + diff --git a/livesupport/modules/storage/etc/testResultToHtml.xsl b/livesupport/modules/storage/etc/testResultToHtml.xsl new file mode 100644 index 000000000..d2165c2a4 --- /dev/null +++ b/livesupport/modules/storage/etc/testResultToHtml.xsl @@ -0,0 +1,63 @@ + + + + + + + LiveSupport unit test results + + +

Preface

+This document is part of the +LiveSupport +project, Copyright © 2004 Media +Development Loan Fund, under the GNU +GPL. +
+This is an automatically generated document. +

Scope

+This document contains the generated unit test results for the +LiveSupport project. +

Summary

+ + + + + + + + + + + + + + + + + + +
Total number of tests:
Tests passed:
Tests failed:
Test errors:
+
+

Tests

+ + + + + + + + + + + + + +
test nametest status
failedpassed
+ + +
+ +
+ diff --git a/livesupport/modules/storage/include/LiveSupport/Storage/StorageClientFactory.h b/livesupport/modules/storage/include/LiveSupport/Storage/StorageClientFactory.h index 3931e9b5b..24c328343 100644 --- a/livesupport/modules/storage/include/LiveSupport/Storage/StorageClientFactory.h +++ b/livesupport/modules/storage/include/LiveSupport/Storage/StorageClientFactory.h @@ -22,7 +22,7 @@ Author : $Author: maroy $ - Version : $Revision: 1.1 $ + Version : $Revision: 1.2 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/include/LiveSupport/Storage/StorageClientFactory.h,v $ ------------------------------------------------------------------------------*/ @@ -63,8 +63,32 @@ using namespace LiveSupport::Core; /** * The factory to create appropriate StorageClient objects. * + * This object has to be configured with an XML configuration element + * called storageClientFactory. This element contains a child element + * specifying and configuring the kind of StorageClient that the + * factory builds. Currently on the TestStorageClient is supported. + * + * A storageClientFactory configuration element may look like the following: + * + *

+ *  <storageClientFactory>
+ *      <testStorage>
+ *          ...
+ *      </testStorage>
+ *  </storageClientFactory>
+ *
+ *  For detais of the testStorage element, see the documentation for the
+ *  TestStorageClient class.
+ *
+ *  The DTD for the above element is:
+ *
+ *  

+ *  <!ELEMENT storageClientFactory (testStorage) >
+ *  
+ * * @author $Author: maroy $ - * @version $Revision: 1.1 $ + * @version $Revision: 1.2 $ + * @see TestStorageClient */ class StorageClientFactory : virtual public Configurable @@ -109,7 +133,7 @@ class StorageClientFactory : * @return the name of the expected XML configuration element. */ static const std::string - configElementName(void) throw () + getConfigElementName(void) throw () { return configElementNameStr; } diff --git a/livesupport/products/scheduler/etc/Makefile.in b/livesupport/products/scheduler/etc/Makefile.in index c813b4e9b..5c00a0711 100644 --- a/livesupport/products/scheduler/etc/Makefile.in +++ b/livesupport/products/scheduler/etc/Makefile.in @@ -21,7 +21,7 @@ # # # Author : $Author: maroy $ -# Version : $Revision: 1.2 $ +# Version : $Revision: 1.3 $ # Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/etc/Makefile.in,v $ # # @configure_input@ @@ -79,6 +79,7 @@ TEST_RESULTS = ${DOC_DIR}/testResults.xml TEST_XSLT = ../etc/testResultToHtml.xsl SCHEDULER_EXE = ${TMP_DIR}/scheduler +SCHEDULER_CFG = ${ETC_DIR}/scheduler.xml TEST_RUNNER = ${TMP_DIR}/testRunner DOXYGEN_CONFIG = ${ETC_DIR}/doxygen.config @@ -120,6 +121,7 @@ SCHEDULER_EXE_LIBS = -l${STORAGE_LIB} -l${DB_LIB} -l${CORE_LIB} \ TEST_RUNNER_OBJS = ${SCHEDULER_OBJS} \ ${TMP_DIR}/SchedulerDaemonTest.o \ + ${TMP_DIR}/SchedulerDaemonUploadTest.o \ ${TMP_DIR}/UploadPlaylistMethodTest.o \ ${TMP_DIR}/PostgresqlScheduleTest.o \ ${TMP_DIR}/TestRunner.o @@ -130,6 +132,7 @@ TEST_RUNNER_LIBS = ${SCHEDULER_EXE_LIBS} -lcppunit -ldl # Targets #------------------------------------------------------------------------------- .PHONY: all dir_setup doc clean docclean depclean distclean +.PHONY: install start run_tests stop uninstall all: dir_setup ${SCHEDULER_EXE} @@ -147,14 +150,33 @@ docclean: ${RM} ${TEST_RESULTS} depclean: clean + ${MAKE} -C ${STORAGE_DIR} clean + ${MAKE} -C ${DB_DIR} clean + ${MAKE} -C ${CORE_DIR} clean distclean: clean docclean ${RMDIR} ${TMP_DIR}/config* ${TMP_DIR}/autom4te* -check: all ${TEST_RUNNER} +check: all ${TEST_RUNNER} start run_tests stop + +run_tests: ${TEST_RUNNER} LD_LIBRARY_PATH=${USR_LIB_DIR} ${TEST_RUNNER} \ -o ${TEST_RESULTS} -s ${TEST_XSLT} +install: ${SCHEDULER_EXE} + LD_LIBRARY_PATH=${USR_LIB_DIR} ${SCHEDULER_EXE} -c ${SCHEDULER_CFG} install + +start: ${SCHEDULER_EXE} + LD_LIBRARY_PATH=${USR_LIB_DIR} ${SCHEDULER_EXE} -c ${SCHEDULER_CFG} start + sleep 2 + +stop: ${SCHEDULER_EXE} + LD_LIBRARY_PATH=${USR_LIB_DIR} ${SCHEDULER_EXE} -c ${SCHEDULER_CFG} stop + +uninstall: ${SCHEDULER_EXE} + LD_LIBRARY_PATH=${USR_LIB_DIR} ${SCHEDULER_EXE} -c ${SCHEDULER_CFG} \ + uninstall + #------------------------------------------------------------------------------- # Specific targets diff --git a/livesupport/products/scheduler/etc/configure.ac b/livesupport/products/scheduler/etc/configure.ac index 747ecef7a..3c74d8423 100644 --- a/livesupport/products/scheduler/etc/configure.ac +++ b/livesupport/products/scheduler/etc/configure.ac @@ -21,7 +21,7 @@ dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA dnl dnl dnl Author : $Author: maroy $ -dnl Version : $Revision: 1.1 $ +dnl Version : $Revision: 1.2 $ dnl Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/etc/configure.ac,v $ dnl----------------------------------------------------------------------------- @@ -35,7 +35,7 @@ dnl----------------------------------------------------------------------------- AC_INIT(Scheduler, 0.1, bugs@campware.org) AC_PREREQ(2.59) AC_COPYRIGHT([Copyright (c) 2004 Media Development Loan Fund under the GNU GPL]) -AC_REVISION($Revision: 1.1 $) +AC_REVISION($Revision: 1.2 $) AC_CONFIG_SRCDIR(../src/main.cxx) @@ -43,6 +43,7 @@ AC_CONFIG_HEADERS(configure.h) AC_PROG_CXX() AC_CHECK_HEADERS(sys/types.h unistd.h getopt.h signal.h sys/stat.h time.h) +AC_CHECK_HEADERS(stdio.h fcntl.h) AC_CONFIG_FILES(../Makefile:../etc/Makefile.in) diff --git a/livesupport/products/scheduler/etc/doxygen.config b/livesupport/products/scheduler/etc/doxygen.config index 9b0c37ea4..d9ddbf251 100644 --- a/livesupport/products/scheduler/etc/doxygen.config +++ b/livesupport/products/scheduler/etc/doxygen.config @@ -21,7 +21,7 @@ # # # Author : $Author: maroy $ -# Version : $Revision: 1.1 $ +# Version : $Revision: 1.2 $ # Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/etc/doxygen.config,v $ #------------------------------------------------------------------------------- @@ -160,7 +160,7 @@ MULTILINE_CPP_IS_BRIEF = YES # If set to NO, the detailed description appears after the member # documentation. -DETAILS_AT_TOP = NO +DETAILS_AT_TOP = YES # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it diff --git a/livesupport/products/scheduler/etc/scheduler.xml b/livesupport/products/scheduler/etc/scheduler.xml index 54bc5f931..528be1a75 100644 --- a/livesupport/products/scheduler/etc/scheduler.xml +++ b/livesupport/products/scheduler/etc/scheduler.xml @@ -1,7 +1,27 @@ + + + + + + + + + + + + + + + + + + + + @@ -11,8 +31,26 @@ ]> + + + + + + + + + + + + + + + diff --git a/livesupport/products/scheduler/src/PostgresqlSchedule.h b/livesupport/products/scheduler/src/PostgresqlSchedule.h index 3a11260f3..0ba269556 100644 --- a/livesupport/products/scheduler/src/PostgresqlSchedule.h +++ b/livesupport/products/scheduler/src/PostgresqlSchedule.h @@ -22,7 +22,7 @@ Author : $Author: maroy $ - Version : $Revision: 1.1 $ + Version : $Revision: 1.2 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/PostgresqlSchedule.h,v $ ------------------------------------------------------------------------------*/ @@ -67,8 +67,21 @@ using namespace LiveSupport::Core; /** * An object containing the schedule of events in a PostreSQL database. * + * This object has to be configured with a simple empty element, as + * the following: + * + *

+ *      <postgresqlSchedule/>
+ *  
+ * + * The DTD for the above element is: + * + *

+ *  <!ELEMENT postgresqlSchedule EMPTY >
+ *  
+ * * @author $Author: maroy $ - * @version $Revision: 1.1 $ + * @version $Revision: 1.2 $ */ class PostgresqlSchedule : public Configurable, public ScheduleInterface diff --git a/livesupport/products/scheduler/src/ScheduleFactory.cxx b/livesupport/products/scheduler/src/ScheduleFactory.cxx index d84f7826a..7ab2f6105 100644 --- a/livesupport/products/scheduler/src/ScheduleFactory.cxx +++ b/livesupport/products/scheduler/src/ScheduleFactory.cxx @@ -22,7 +22,7 @@ Author : $Author: maroy $ - Version : $Revision: 1.1 $ + Version : $Revision: 1.2 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/ScheduleFactory.cxx,v $ ------------------------------------------------------------------------------*/ @@ -115,3 +115,30 @@ ScheduleFactory :: configure(const xmlpp::Element & element) } +/*------------------------------------------------------------------------------ + * Install the schedule factory. + *----------------------------------------------------------------------------*/ +void +ScheduleFactory :: install(void) throw (std::exception) +{ + if (!schedule) { + throw std::logic_error("ScheduleFactory not yet configured"); + } + + schedule->install(); +} + + +/*------------------------------------------------------------------------------ + * Install the schedule factory. + *----------------------------------------------------------------------------*/ +void +ScheduleFactory :: uninstall(void) throw (std::exception) +{ + if (!schedule) { + throw std::logic_error("ScheduleFactory not yet configured"); + } + + schedule->uninstall(); +} + diff --git a/livesupport/products/scheduler/src/ScheduleFactory.h b/livesupport/products/scheduler/src/ScheduleFactory.h index e25be6baa..ebbbfe8cf 100644 --- a/livesupport/products/scheduler/src/ScheduleFactory.h +++ b/livesupport/products/scheduler/src/ScheduleFactory.h @@ -22,7 +22,7 @@ Author : $Author: maroy $ - Version : $Revision: 1.1 $ + Version : $Revision: 1.2 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/ScheduleFactory.h,v $ ------------------------------------------------------------------------------*/ @@ -43,6 +43,7 @@ #include #include "LiveSupport/Core/Configurable.h" +#include "LiveSupport/Core/Installable.h" #include "ScheduleInterface.h" @@ -63,11 +64,33 @@ using namespace LiveSupport::Core; /** * The factory to create appropriate Schedule objects. * + * This object has to be configured with an element that contains + * the configuration element that the factory should build. + * Currently only PostgresqlSchedule is supported by this factory. + * + * An example configuration element is the following: + * + *

+ *      <scheduleFactory>
+ *          <postgresqlSchedule/>
+ *      </scheduleFactory>
+ *  
+ * + * The DTD for the above element is: + * + *

+ *  <!ELEMENT scheduleFactory (postgresqlSchedule) >
+ *  
+ * + * For details on the <postgreslSchedule> element, see the + * PostgresqlSchedule documentation. + * * @author $Author: maroy $ - * @version $Revision: 1.1 $ + * @version $Revision: 1.2 $ + * @see PostgresqlSchedule */ -class ScheduleFactory : - virtual public Configurable +class ScheduleFactory : virtual public Configurable, + virtual public Installable { private: /** @@ -109,7 +132,7 @@ class ScheduleFactory : * @return the name of the expected XML configuration element. */ static const std::string - configElementName(void) throw () + getConfigElementName(void) throw () { return configElementNameStr; } @@ -136,6 +159,28 @@ class ScheduleFactory : throw (std::invalid_argument, std::logic_error); + /** + * Install the component. + * This step involves creating the environment in which the component + * will run. This may be creation of coniguration files, + * database tables, etc. + * + * @exception std::exception on installation problems, + * especially if the ScheduleFactory was not yet configured. + */ + virtual void + install(void) throw (std::exception); + + /** + * Uninstall the component. + * Removes all the resources created in the install step. + * + * @exception std::exception on unistallation problems, + e especially if the ScheduleFactory was not yet configured. + */ + virtual void + uninstall(void) throw (std::exception); + /** * Return a schedule. * diff --git a/livesupport/products/scheduler/src/SchedulerDaemon.cxx b/livesupport/products/scheduler/src/SchedulerDaemon.cxx index cfcb49246..e29be8a1b 100644 --- a/livesupport/products/scheduler/src/SchedulerDaemon.cxx +++ b/livesupport/products/scheduler/src/SchedulerDaemon.cxx @@ -22,7 +22,7 @@ Author : $Author: maroy $ - Version : $Revision: 1.1 $ + Version : $Revision: 1.2 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/SchedulerDaemon.cxx,v $ ------------------------------------------------------------------------------*/ @@ -51,9 +51,14 @@ #include #include +#include "LiveSupport/Db/ConnectionManagerFactory.h" +#include "LiveSupport/Storage/StorageClientFactory.h" +#include "ScheduleFactory.h" #include "SchedulerDaemon.h" +using namespace LiveSupport::Db; +using namespace LiveSupport::Storage; using namespace LiveSupport::Scheduler; /* =================================================== local data structures */ @@ -64,7 +69,7 @@ using namespace LiveSupport::Scheduler; /** * The singleton instance of the Scheduler daemon object. */ -SchedulerDaemon * SchedulerDaemon::schedulerDaemon = 0; +Ptr::Ref SchedulerDaemon::schedulerDaemon; /** * The name of the XML configuration element for the Scheduler daemon. @@ -86,16 +91,17 @@ static const std::string xmlRpcDaemonConfElement = "xmlRpcDaemon"; /*------------------------------------------------------------------------------ * Return the singleton instnace. *----------------------------------------------------------------------------*/ -class SchedulerDaemon * +class Ptr::Ref SchedulerDaemon :: getInstance (void) throw () { if (!schedulerDaemon) { - schedulerDaemon = new SchedulerDaemon(); + schedulerDaemon.reset(new SchedulerDaemon()); } return schedulerDaemon; } + /*------------------------------------------------------------------------------ * Configure the scheduler daemon *----------------------------------------------------------------------------*/ @@ -110,10 +116,77 @@ SchedulerDaemon :: configure(const xmlpp::Element & element) throw std::invalid_argument(eMsg); } - xmlpp::Node::NodeList nodes = - element.get_children(xmlRpcDaemonConfElement); + xmlpp::Node::NodeList nodes; + + // configure the ConnectionManagerFactory + nodes = + element.get_children(ConnectionManagerFactory::getConfigElementName()); + if (nodes.size() < 1) { + throw std::invalid_argument("no connectionManagerFactory element"); + } + Ptr::Ref cmf + = ConnectionManagerFactory::getInstance(); + cmf->configure( *((const xmlpp::Element*) *(nodes.begin())) ); + + // configure the StorageClientFactory + nodes = element.get_children(StorageClientFactory::getConfigElementName()); + if (nodes.size() < 1) { + throw std::invalid_argument("no storageClientFactory element"); + } + Ptr::Ref scf = StorageClientFactory::getInstance(); + scf->configure( *((const xmlpp::Element*) *(nodes.begin())) ); + + // configure the ScheduleFactory + nodes = element.get_children(ScheduleFactory::getConfigElementName()); + if (nodes.size() < 1) { + throw std::invalid_argument("no scheduleFactory element"); + } + Ptr::Ref sf = ScheduleFactory::getInstance(); + sf->configure( *((const xmlpp::Element*) *(nodes.begin())) ); + + // configure the XmlRpcDaemon + nodes = element.get_children(XmlRpcDaemon::getConfigElementName()); if (nodes.size() < 1) { throw std::invalid_argument("no xmlRpcDaemon element"); } configureXmlRpcDaemon( *((const xmlpp::Element*) *(nodes.begin())) ); + } + + +/*------------------------------------------------------------------------------ + * Register our XML-RPC methods + *----------------------------------------------------------------------------*/ +void +SchedulerDaemon :: registerXmlRpcFunctions( + Ptr::Ref xmlRpcServer) + throw (std::logic_error) +{ + xmlRpcServer->addMethod(uploadPlaylistMethod.get()); +} + + +/*------------------------------------------------------------------------------ + * Install the scheduler daemon. + *----------------------------------------------------------------------------*/ +void +SchedulerDaemon :: install(void) throw (std::exception) +{ + // TODO: check if we have already been configured + Ptr::Ref sf = ScheduleFactory::getInstance(); + sf->install(); +} + + +/*------------------------------------------------------------------------------ + * Install the scheduler daemon. + *----------------------------------------------------------------------------*/ +void +SchedulerDaemon :: uninstall(void) throw (std::exception) +{ + // TODO: check if we have already been configured + Ptr::Ref sf = ScheduleFactory::getInstance(); + sf->uninstall(); +} + + diff --git a/livesupport/products/scheduler/src/SchedulerDaemon.h b/livesupport/products/scheduler/src/SchedulerDaemon.h index 72e0ab17c..c17a8155b 100644 --- a/livesupport/products/scheduler/src/SchedulerDaemon.h +++ b/livesupport/products/scheduler/src/SchedulerDaemon.h @@ -22,7 +22,7 @@ Author : $Author: maroy $ - Version : $Revision: 1.1 $ + Version : $Revision: 1.2 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/SchedulerDaemon.h,v $ ------------------------------------------------------------------------------*/ @@ -57,12 +57,18 @@ #include #include +#include "LiveSupport/Core/Ptr.h" +#include "LiveSupport/Core/Installable.h" +#include "LiveSupport/Core/Configurable.h" +#include "UploadPlaylistMethod.h" #include "XmlRpcDaemon.h" namespace LiveSupport { namespace Scheduler { +using namespace LiveSupport::Core; + /* ================================================================ constants */ @@ -76,17 +82,59 @@ namespace Scheduler { * This class is responsible for starting, running and stopping the * Scheduler daemon. * + * The SchedulerDaemon has to configured by an XML element called + * scheduler. This element contains configuration elements for the + * compontents used by the scheduler. The configuration file looks + * like the following: + * + *

+ *  <scheduler>
+ *      <connectionManagerFactory>
+ *          ...
+ *      </connectionManagerFactory>
+ *      <storageClientFactory>
+ *          ...
+ *      </storageClientFactory>
+ *      <scheduleFactory>
+ *          ...
+ *      </scheduleFactory>
+ *      <xmlRpcDaemon>
+ *          ...
+ *      </xmlRpcDaemon>
+ *  </scheduler>
+ *  
+ * + * For details on the included elements, see the corresponding documentation + * for XmlRpcDaemon, ConnectionManagerFactory and ScheduleFactory. + * + * The DTD for the above element is the following: + * + *

+ *  <!ELEMENT scheduler (connectionManagerFactory,storageClientFactory,
+ *                          scheduleFactory,xmlRpcDaemon) >
+ *  
+ * * @author $Author: maroy $ - * @version $Revision: 1.1 $ + * @version $Revision: 1.2 $ + * @see XmlRpcDaemon + * @see ConnectionManagerFactory + * @see ScheduleFactory */ -class SchedulerDaemon : public XmlRpcDaemon +class SchedulerDaemon : public Installable, + public Configurable, + public XmlRpcDaemon { private: /** * The singleton instance of the scheduler daemon. */ - static SchedulerDaemon * schedulerDaemon; + static Ptr::Ref schedulerDaemon; + + /** + * The UploadPlaylistMethod the daemon is providing. + */ + Ptr::Ref uploadPlaylistMethod; /** * Default constructor. @@ -94,6 +142,7 @@ class SchedulerDaemon : public XmlRpcDaemon SchedulerDaemon (void) throw () : XmlRpcDaemon() { + uploadPlaylistMethod.reset(new UploadPlaylistMethod()); } protected: @@ -102,19 +151,25 @@ class SchedulerDaemon : public XmlRpcDaemon * Register your XML-RPC functions by implementing this function. */ virtual void - registerXmlRpcFunctions(XmlRpc::XmlRpcServer & xmlRpcServer) - throw (std::logic_error) - { - } + registerXmlRpcFunctions(Ptr::Ref xmlRpcServer) + throw (std::logic_error); public: + /** + * Virtual destructor. + */ + virtual + ~SchedulerDaemon(void) throw () + { + } + /** * Return a pointer to the singleton instance of SchedulerDaemon. * * @return a pointer to the singleton instance of SchedulerDaemon */ - static SchedulerDaemon * + static Ptr::Ref getInstance (void) throw (); /** @@ -133,6 +188,25 @@ class SchedulerDaemon : public XmlRpcDaemon throw (std::invalid_argument, std::logic_error); + /** + * Install the component. + * This step involves creating the environment in which the component + * will run. This may be creation of coniguration files, + * database tables, etc. + * + * @exception std::exception on installation problems. + */ + virtual void + install(void) throw (std::exception); + + /** + * Uninstall the component. + * Removes all the resources created in the install step. + * + * @exception std::exception on unistallation problems. + */ + virtual void + uninstall(void) throw (std::exception); }; diff --git a/livesupport/products/scheduler/src/SchedulerDaemonTest.cxx b/livesupport/products/scheduler/src/SchedulerDaemonTest.cxx index f528835a7..e31cd4a80 100644 --- a/livesupport/products/scheduler/src/SchedulerDaemonTest.cxx +++ b/livesupport/products/scheduler/src/SchedulerDaemonTest.cxx @@ -22,7 +22,7 @@ Author : $Author: maroy $ - Version : $Revision: 1.1 $ + Version : $Revision: 1.2 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/SchedulerDaemonTest.cxx,v $ ------------------------------------------------------------------------------*/ @@ -72,7 +72,7 @@ static const std::string configFileName = "etc/scheduler.xml"; void SchedulerDaemonTest :: setUp(void) throw () { - SchedulerDaemon * daemon = SchedulerDaemon::getInstance(); + Ptr::Ref daemon = SchedulerDaemon::getInstance(); if (!daemon->isConfigured()) { try { @@ -104,7 +104,9 @@ SchedulerDaemonTest :: tearDown(void) throw () void SchedulerDaemonTest :: getSingleton(void) throw (CPPUNIT_NS::Exception) { - CPPUNIT_ASSERT( SchedulerDaemon::getInstance() ); + Ptr::Ref daemon = SchedulerDaemon::getInstance(); + + CPPUNIT_ASSERT( daemon.get() ); } @@ -114,9 +116,9 @@ SchedulerDaemonTest :: getSingleton(void) throw (CPPUNIT_NS::Exception) void SchedulerDaemonTest :: testStartStop(void) throw (CPPUNIT_NS::Exception) { - SchedulerDaemon * daemon = SchedulerDaemon::getInstance(); + Ptr::Ref daemon = SchedulerDaemon::getInstance(); - CPPUNIT_ASSERT( daemon ); + CPPUNIT_ASSERT( daemon.get() ); CPPUNIT_ASSERT( !(daemon->isRunning()) ); daemon->start(); sleep(3); diff --git a/livesupport/products/scheduler/src/SchedulerDaemonUploadTest.cxx b/livesupport/products/scheduler/src/SchedulerDaemonUploadTest.cxx new file mode 100644 index 000000000..be5f7ac65 --- /dev/null +++ b/livesupport/products/scheduler/src/SchedulerDaemonUploadTest.cxx @@ -0,0 +1,135 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2004 Media Development Loan Fund + + This file is part of the LiveSupport project. + http://livesupport.campware.org/ + To report bugs, send an e-mail to bugs@campware.org + + LiveSupport 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. + + LiveSupport 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 LiveSupport; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + Author : $Author: maroy $ + Version : $Revision: 1.1 $ + Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/Attic/SchedulerDaemonUploadTest.cxx,v $ + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#if HAVE_UNISTD_H +#include +#else +#error "Need unistd.h" +#endif + + +#include +#include +#include + +#include "SchedulerDaemon.h" +#include "SchedulerDaemonUploadTest.h" + + +using namespace XmlRpc; +using namespace LiveSupport::Scheduler; + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +CPPUNIT_TEST_SUITE_REGISTRATION(SchedulerDaemonUploadTest); + +/** + * The name of the configuration file for the scheduler daemon. + */ +static const std::string configFileName = "etc/scheduler.xml"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Set up the test environment + *----------------------------------------------------------------------------*/ +void +SchedulerDaemonUploadTest :: setUp(void) throw () +{ + Ptr::Ref daemon = SchedulerDaemon::getInstance(); + + if (!daemon->isConfigured()) { + try { + std::auto_ptr + parser(new xmlpp::DomParser(configFileName, true)); + const xmlpp::Document * document = parser->get_document(); + daemon->configure(*(document->get_root_node())); + } catch (std::invalid_argument &e) { + std::cerr << e.what() << std::endl; + CPPUNIT_FAIL("semantic error in configuration file"); + } catch (xmlpp::exception &e) { + std::cerr << e.what() << std::endl; + CPPUNIT_FAIL("error parsing configuration file"); + } + } + + daemon->install(); +// daemon->start(); +// sleep(5); +} + + +/*------------------------------------------------------------------------------ + * Clean up the test environment + *----------------------------------------------------------------------------*/ +void +SchedulerDaemonUploadTest :: tearDown(void) throw () +{ + Ptr::Ref daemon = SchedulerDaemon::getInstance(); + +// daemon->stop(); + daemon->uninstall(); +} + + +/*------------------------------------------------------------------------------ + * Test a simple upload. + *----------------------------------------------------------------------------*/ +void +SchedulerDaemonUploadTest :: simpleTest(void) + throw (CPPUNIT_NS::Exception) +{ + XmlRpcValue parameters; + XmlRpcValue result; + struct tm time; + + XmlRpcClient xmlRpcClient("localhost", 3344, "/RPC2", false); + + // try to schedule playlist #1 for the time below + parameters["playlistId"] = 1; + strptime("2001-11-12 10:00:00", "%Y-%m-%d %H:%M:%S", &time); + parameters["playtime"] = &time; + + xmlRpcClient.execute("uploadPlaylist", parameters, result); + CPPUNIT_ASSERT(result); +} + diff --git a/livesupport/products/scheduler/src/SchedulerDaemonUploadTest.h b/livesupport/products/scheduler/src/SchedulerDaemonUploadTest.h new file mode 100644 index 000000000..a44fb42fd --- /dev/null +++ b/livesupport/products/scheduler/src/SchedulerDaemonUploadTest.h @@ -0,0 +1,108 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2004 Media Development Loan Fund + + This file is part of the LiveSupport project. + http://livesupport.campware.org/ + To report bugs, send an e-mail to bugs@campware.org + + LiveSupport 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. + + LiveSupport 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 LiveSupport; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + Author : $Author: maroy $ + Version : $Revision: 1.1 $ + Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/Attic/SchedulerDaemonUploadTest.h,v $ + +------------------------------------------------------------------------------*/ +#ifndef SchedulerDaemonUploadTest_h +#define SchedulerDaemonUploadTest_h + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#include + + +namespace LiveSupport { +namespace Scheduler { + +using namespace LiveSupport; + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * Unit test to test the uploadPlaylist XML-RPC call. + * + * @author $Author: maroy $ + * @version $Revision: 1.1 $ + * @see SchedulerDaemon + */ +class SchedulerDaemonUploadTest : public CPPUNIT_NS::TestFixture +{ + CPPUNIT_TEST_SUITE(SchedulerDaemonUploadTest); + CPPUNIT_TEST(simpleTest); + CPPUNIT_TEST_SUITE_END(); + + protected: + + /** + * Simple test for playlist uploading. + * + * @exception CPPUNIT_NS::Exception on test failures. + */ + void + simpleTest(void) throw (CPPUNIT_NS::Exception); + + public: + + /** + * Set up the environment for the test case. + */ + void + setUp(void) throw (); + + /** + * Clean up the environment after the test case. + */ + void + tearDown(void) throw (); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + +} // namespace Scheduler +} // namespace LiveSupport + +#endif // SchedulerDaemonUploadTest_h + diff --git a/livesupport/products/scheduler/src/UploadPlaylistMethod.cxx b/livesupport/products/scheduler/src/UploadPlaylistMethod.cxx index ec52510b3..308fe717f 100644 --- a/livesupport/products/scheduler/src/UploadPlaylistMethod.cxx +++ b/livesupport/products/scheduler/src/UploadPlaylistMethod.cxx @@ -22,7 +22,7 @@ Author : $Author: maroy $ - Version : $Revision: 1.1 $ + Version : $Revision: 1.2 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/UploadPlaylistMethod.cxx,v $ ------------------------------------------------------------------------------*/ @@ -65,7 +65,7 @@ using namespace LiveSupport::Scheduler; /*------------------------------------------------------------------------------ * The name of this XML-RPC method. *----------------------------------------------------------------------------*/ -const std::string UploadPlaylistMethod::methodName = "stop"; +const std::string UploadPlaylistMethod::methodName = "uploadPlaylist"; /*------------------------------------------------------------------------------ * The name of the playlist id member in the XML-RPC parameter @@ -74,10 +74,10 @@ const std::string UploadPlaylistMethod::methodName = "stop"; const std::string UploadPlaylistMethod::playlistIdName = "playlistId"; /*------------------------------------------------------------------------------ - * The name of the playlength member in the XML-RPC parameter + * The name of the playtime member in the XML-RPC parameter * structure. *----------------------------------------------------------------------------*/ -const std::string UploadPlaylistMethod::playlengthName = "playlength"; +const std::string UploadPlaylistMethod::playtimeName = "playtime"; /* =============================================== local function prototypes */ @@ -120,11 +120,11 @@ UploadPlaylistMethod :: extractPlayschedule( XmlRpc::XmlRpcValue & xmlRpcValue) throw (std::invalid_argument) { - if (!xmlRpcValue.hasMember(playlengthName)) { - throw std::invalid_argument("no playlength in parameter structure"); + if (!xmlRpcValue.hasMember(playtimeName)) { + throw std::invalid_argument("no playtime in parameter structure"); } - struct tm & tm = (struct tm &) xmlRpcValue[playlengthName]; + struct tm & tm = (struct tm &) xmlRpcValue[playtimeName]; time_t time = mktime(&tm); Ptr::Ref ptime(new ptime(from_time_t(time))); @@ -141,8 +141,14 @@ UploadPlaylistMethod :: execute( XmlRpc::XmlRpcValue & parameters, throw () { try { - Ptr::Ref id = extractPlaylistId(parameters); - Ptr::Ref playschedule = extractPlayschedule(parameters); + if (!parameters.valid()) { + // TODO: mark error + returnValue = XmlRpc::XmlRpcValue(false); + return; + } + + Ptr::Ref id = extractPlaylistId(parameters[0]); + Ptr::Ref playschedule = extractPlayschedule(parameters[0]); Ptr::Ref scf; Ptr::Ref storage; diff --git a/livesupport/products/scheduler/src/UploadPlaylistMethod.h b/livesupport/products/scheduler/src/UploadPlaylistMethod.h index 3ad7a66e1..4a6b3ae82 100644 --- a/livesupport/products/scheduler/src/UploadPlaylistMethod.h +++ b/livesupport/products/scheduler/src/UploadPlaylistMethod.h @@ -22,7 +22,7 @@ Author : $Author: maroy $ - Version : $Revision: 1.1 $ + Version : $Revision: 1.2 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/UploadPlaylistMethod.h,v $ ------------------------------------------------------------------------------*/ @@ -68,8 +68,17 @@ using namespace LiveSupport::Core; * An XML-RPC method object to accept a playlist for upload, * and schedule it in the scheduler. * + * The name of the method when called through XML-RPC is "uploadPlaylist". + * The expected parameter is an XML-RPC structure, with the following + * member: + *
    + *
  • playlistId - int, the id of the playlist to upload
  • + *
  • playtime - the time when the playlist should be scheduled, + * an ISO 8601 DateTime field
  • + *
+ * * @author $Author: maroy $ - * @version $Revision: 1.1 $ + * @version $Revision: 1.2 $ */ class UploadPlaylistMethod : public XmlRpc::XmlRpcServerMethod { @@ -87,10 +96,10 @@ class UploadPlaylistMethod : public XmlRpc::XmlRpcServerMethod static const std::string playlistIdName; /** - * The name of the playlength member in the XML-RPC parameter + * The name of the playtime member in the XML-RPC parameter * structure. */ - static const std::string playlengthName; + static const std::string playtimeName; /** * Extract the playlist id from the XML-RPC parameters. diff --git a/livesupport/products/scheduler/src/UploadPlaylistMethodTest.cxx b/livesupport/products/scheduler/src/UploadPlaylistMethodTest.cxx index 3d98a2f2f..41ad917c7 100644 --- a/livesupport/products/scheduler/src/UploadPlaylistMethodTest.cxx +++ b/livesupport/products/scheduler/src/UploadPlaylistMethodTest.cxx @@ -22,7 +22,7 @@ Author : $Author: maroy $ - Version : $Revision: 1.1 $ + Version : $Revision: 1.2 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/UploadPlaylistMethodTest.cxx,v $ ------------------------------------------------------------------------------*/ @@ -152,6 +152,7 @@ UploadPlaylistMethodTest :: firstTest(void) throw (CPPUNIT_NS::Exception) { Ptr::Ref method(new UploadPlaylistMethod()); + XmlRpc::XmlRpcValue rootParameter; XmlRpc::XmlRpcValue parameters; XmlRpc::XmlRpcValue result; struct tm time; @@ -159,9 +160,10 @@ UploadPlaylistMethodTest :: firstTest(void) // set up a structure for the parameters parameters["playlistId"] = 1; strptime("2001-11-12 18:31:01", "%Y-%m-%d %H:%M:%S", &time); - parameters["playlength"] = &time; + parameters["playtime"] = &time; + rootParameter[0] = parameters; - method->execute(parameters, result); + method->execute(rootParameter, result); CPPUNIT_ASSERT(result); } @@ -174,6 +176,7 @@ UploadPlaylistMethodTest :: overlappingPlaylists(void) throw (CPPUNIT_NS::Exception) { Ptr::Ref method(new UploadPlaylistMethod()); + XmlRpc::XmlRpcValue rootParameter; XmlRpc::XmlRpcValue parameters; XmlRpc::XmlRpcValue result; struct tm time; @@ -181,34 +184,38 @@ UploadPlaylistMethodTest :: overlappingPlaylists(void) // load the first playlist, this will succeed parameters["playlistId"] = 1; strptime("2001-11-12 10:00:00", "%Y-%m-%d %H:%M:%S", &time); - parameters["playlength"] = &time; + parameters["playtime"] = &time; + rootParameter[0] = parameters; - method->execute(parameters, result); + method->execute(rootParameter, result); CPPUNIT_ASSERT(result); // try to load the same one, but in an overlapping time region // (we know that playlist with id 1 in 1 hour long) parameters["playlistId"] = 1; strptime("2001-11-12 10:30:00", "%Y-%m-%d %H:%M:%S", &time); - parameters["playlength"] = &time; + parameters["playtime"] = &time; + rootParameter[0] = parameters; - method->execute(parameters, result); + method->execute(rootParameter, result); CPPUNIT_ASSERT(!result); // try to load the same one, but now in good timing parameters["playlistId"] = 1; strptime("2001-11-12 11:30:00", "%Y-%m-%d %H:%M:%S", &time); - parameters["playlength"] = &time; + parameters["playtime"] = &time; + rootParameter[0] = parameters; - method->execute(parameters, result); + method->execute(rootParameter, result); CPPUNIT_ASSERT(result); // try to load the same one, this time overlapping both previos instnaces parameters["playlistId"] = 1; strptime("2001-11-12 10:45:00", "%Y-%m-%d %H:%M:%S", &time); - parameters["playlength"] = &time; + parameters["playtime"] = &time; + rootParameter[0] = parameters; - method->execute(parameters, result); + method->execute(rootParameter, result); CPPUNIT_ASSERT(!result); } diff --git a/livesupport/products/scheduler/src/XmlRpcDaemon.cxx b/livesupport/products/scheduler/src/XmlRpcDaemon.cxx index eade4c891..cfeaa0894 100644 --- a/livesupport/products/scheduler/src/XmlRpcDaemon.cxx +++ b/livesupport/products/scheduler/src/XmlRpcDaemon.cxx @@ -22,7 +22,7 @@ Author : $Author: maroy $ - Version : $Revision: 1.1 $ + Version : $Revision: 1.2 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/XmlRpcDaemon.cxx,v $ ------------------------------------------------------------------------------*/ @@ -33,6 +33,24 @@ #include "configure.h" #endif +#if HAVE_STDIO_H +#include +#else +#error "Need stdio.h" +#endif + +#if HAVE_UNISTD_H +#include +#else +#error "Need unistd.h" +#endif + +#if HAVE_FCNTL_H +#include +#else +#error "Need fcntl.h" +#endif + #if HAVE_SIGNAL_H #include #else @@ -63,10 +81,11 @@ using namespace LiveSupport::Scheduler; /* ================================================ local constants & macros */ -/** - * The name of the XML configuration element for the Scheduler daemon. - */ -static const std::string confElement = "xmlRpcDaemon"; +/*------------------------------------------------------------------------------ + * The name of the config element for this class + *----------------------------------------------------------------------------*/ +const std::string XmlRpcDaemon::configElementNameStr = + "xmlRpcDaemon"; /** * The name of the XML configuration attribute for the XML-RPC host name. @@ -110,7 +129,7 @@ XmlRpcDaemon :: configureXmlRpcDaemon( const xmlpp::Attribute * attribute; std::stringstream strStr; - if (element.get_name() != confElement) { + if (element.get_name() != configElementNameStr) { std::string eMsg = "Bad configuration element "; eMsg += element.get_name(); throw std::invalid_argument(eMsg); @@ -148,14 +167,14 @@ XmlRpcDaemon :: configureXmlRpcDaemon( * http://www.linuxprofilm.com/articles/linux-daemon-howto.html * for hints. *----------------------------------------------------------------------------*/ -void +bool XmlRpcDaemon :: daemonize(void) throw (std::runtime_error) { int i; if (getppid() == 1) { // we're already a daemon - return; + return true; } i = fork(); @@ -163,7 +182,15 @@ XmlRpcDaemon :: daemonize(void) throw (std::runtime_error) throw std::runtime_error("fork error"); } else if (i > 0) { // this is the parent, simply return - return; + return false; + } + // for twice, so that we're totally detached from our ancestor + i = fork(); + if (i < 0) { + throw std::runtime_error("fork error"); + } else if (i > 0) { + // this is the parent, simply return + return false; } // now we're in the child process @@ -174,23 +201,24 @@ XmlRpcDaemon :: daemonize(void) throw (std::runtime_error) // change the umask umask(uMask); + /* TODO: wait with this until we have logging // close standard file descriptors - /* TODO: don't close these until we don't have logging - std::cin.close(); - std::cout.close(); - std::cerr.close(); + for (i=getdtablesize();i>=0;--i) close(i); // + + // set all std in/out to /dev/null + i=open("/dev/null",O_RDWR); // open stdin + dup(i); // stdout + dup(i); // stderr */ // save the process id savePid(); // ignore some signals - /* TODO signal(SIGCHLD,SIG_IGN); signal(SIGTSTP,SIG_IGN); signal(SIGTTOU,SIG_IGN); signal(SIGTTIN,SIG_IGN); - */ // register our signal hanlder SignalDispatcher * signalDispatcher = SignalDispatcher::getInstance(); @@ -200,6 +228,8 @@ XmlRpcDaemon :: daemonize(void) throw (std::runtime_error) signalDispatcher->registerHandler(SIGTERM, handler); // FIXME: this signal handler will not be deleted by anyone, // poddible memory leak + + return true; } @@ -245,16 +275,19 @@ XmlRpcDaemon :: start (void) throw (std::logic_error) checkForConfiguration(); if (background) { - daemonize(); + if (!daemonize()) { + // return if we're the parent process that should not continue + return; + } } // and now our own XML-RPC methods registerXmlRpcFunctions(xmlRpcServer); // bind & run - XmlRpc::setVerbosity(5); - xmlRpcServer.bindAndListen(xmlRpcPort); - xmlRpcServer.work(-1.0); + xmlRpcServer->enableIntrospection(true); + xmlRpcServer->bindAndListen(xmlRpcPort); + xmlRpcServer->work(-1.0); } @@ -266,7 +299,17 @@ XmlRpcDaemon :: isRunning (void) throw (std::logic_error) { checkForConfiguration(); - return loadPid(); + pid_t pid = loadPid(); + // check if there is a stale pid stored + if (pid && kill(pid, 0)) { + if (errno == ESRCH) { + // the pid does not exist, remove the stale pid file + remove(pidFileName.c_str()); + pid = 0; + } + } + + return pid; } @@ -291,7 +334,7 @@ XmlRpcDaemon :: shutdown (void) throw (std::logic_error) { checkForConfiguration(); - xmlRpcServer.shutdown(); + xmlRpcServer->shutdown(); remove(pidFileName.c_str()); } diff --git a/livesupport/products/scheduler/src/XmlRpcDaemon.h b/livesupport/products/scheduler/src/XmlRpcDaemon.h index 84dc62777..27c91a0a4 100644 --- a/livesupport/products/scheduler/src/XmlRpcDaemon.h +++ b/livesupport/products/scheduler/src/XmlRpcDaemon.h @@ -22,7 +22,7 @@ Author : $Author: maroy $ - Version : $Revision: 1.1 $ + Version : $Revision: 1.2 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/XmlRpcDaemon.h,v $ ------------------------------------------------------------------------------*/ @@ -57,10 +57,15 @@ #include #include +#include "LiveSupport/Core/Ptr.h" + namespace LiveSupport { namespace Scheduler { +using namespace XmlRpc; +using namespace LiveSupport::Core; + /* ================================================================ constants */ @@ -114,11 +119,15 @@ namespace Scheduler { * * * @author $Author: maroy $ - * @version $Revision: 1.1 $ + * @version $Revision: 1.2 $ */ class XmlRpcDaemon { private: + /** + * The name of the configuration XML elmenent used by this object. + */ + static const std::string configElementNameStr; /** * The host the XML-RPC server the daemon is @@ -154,14 +163,16 @@ class XmlRpcDaemon /** * The XML-RPC server running within the Scheduler Daemon. */ - XmlRpc::XmlRpcServer xmlRpcServer; + Ptr::Ref xmlRpcServer; /** * Do all the necessary tasks of becoming a daemon. * + * @return true if we're in the daemon process, false + * if we're in the parent process that should not continue * @exception std::runtime_error on forking errors */ - void + bool daemonize(void) throw (std::runtime_error); /** @@ -179,7 +190,6 @@ class XmlRpcDaemon loadPid(void) throw(); protected: - /** * Default constructor. */ @@ -187,6 +197,7 @@ class XmlRpcDaemon { background = true; configured = false; + xmlRpcServer.reset(new XmlRpcServer()); } /** @@ -233,11 +244,22 @@ class XmlRpcDaemon * Register your XML-RPC functions by implementing this function. */ virtual void - registerXmlRpcFunctions(XmlRpc::XmlRpcServer & xmlRpcServer) + registerXmlRpcFunctions(Ptr::Ref xmlRpcServer) throw (std::logic_error) = 0; public: + /** + * Return the name of the XML element this object expects + * to be sent to a call to configure(). + * + * @return the name of the expected XML configuration element. + */ + static const std::string + getConfigElementName(void) throw () + { + return configElementNameStr; + } /** * Tell if the daemon has already been configured. @@ -353,9 +375,11 @@ class XmlRpcDaemon start (void) throw (std::logic_error); /** - * Tell if the deamon is running. + * Tell if the daemon is running. + * If there is a stale pid file stored for the daemon, it is + * removed during checking (and correctly false is returned). * - * @return true of the deamon is running, false otherwise. + * @return true of the daemon is running, false otherwise. * @exception std::logic_error if the daemon has not * yet been configured. */ diff --git a/livesupport/products/scheduler/src/main.cxx b/livesupport/products/scheduler/src/main.cxx index 256afc579..eb3acce7a 100644 --- a/livesupport/products/scheduler/src/main.cxx +++ b/livesupport/products/scheduler/src/main.cxx @@ -22,7 +22,7 @@ Author : $Author: maroy $ - Version : $Revision: 1.1 $ + Version : $Revision: 1.2 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/main.cxx,v $ ------------------------------------------------------------------------------*/ @@ -86,6 +86,11 @@ static const struct option longOptions[] = { { 0, 0, 0, 0 } }; +/** + * The start command: "install" + */ +static const std::string installCommand = "install"; + /** * The start command: "start" */ @@ -101,6 +106,11 @@ static const std::string statusCommand = "status"; */ static const std::string stopCommand = "stop"; +/** + * The stop command: "uninstall" + */ +static const std::string uninstallCommand = "uninstall"; + /* =============================================== local function prototypes */ @@ -170,7 +180,7 @@ int main ( int argc, std::cerr << "using config file '" << configFileName << '\'' << std::endl; - SchedulerDaemon * daemon = SchedulerDaemon::getInstance(); + Ptr::Ref daemon = SchedulerDaemon::getInstance(); try { std::auto_ptr @@ -189,7 +199,9 @@ int main ( int argc, daemon->setBackground(!debugMode); - if (startCommand == argv[optind]) { + if (installCommand == argv[optind]) { + daemon->install(); + } else if (startCommand == argv[optind]) { daemon->start(); } else if (statusCommand == argv[optind]) { std::cout << "The Scheduler Daemon is " @@ -197,6 +209,8 @@ int main ( int argc, << "running" << std::endl; } else if (stopCommand == argv[optind]) { daemon->stop(); + } else if (uninstallCommand == argv[optind]) { + daemon->uninstall(); } else { printUsage(argv[0], std::cout); return 1; @@ -228,7 +242,8 @@ printUsage ( const char invocation[], << std::endl << "Usage: " << invocation << " [OPTION] COMMAND" << std::endl - << " COMMAND is one of: start, stop or status" << std::endl + << " COMMAND is one of: install, start, stop, status or uninstall" + << std::endl << std::endl << " mandatory options:" << std::endl << " -c, --config=file.name scheduler configuration file" << std::endl