added initial version of the scheduler product

This commit is contained in:
maroy 2004-07-23 18:34:27 +00:00
parent 628c515e6c
commit 6a6518dbca
33 changed files with 5500 additions and 0 deletions

View File

@ -0,0 +1,87 @@
#!/bin/sh
#-------------------------------------------------------------------------------
# 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/bin/autogen.sh,v $
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# Run this to set up the build system: configure, makefiles, etc.
# (based on the version in enlightenment's cvs)
#-------------------------------------------------------------------------------
package="Scheduler"
# assume we're in $basedir/bin
basedir=`dirname $0`/..
test -z "$basedir" && basedir=.
tmpdir=$basedir/tmp
cd "$tmpdir"
DIE=0
# look at all other directories as seen from ${basedir}/tmp
tmpdir=.
bindir=../bin
etcdir=../etc
(autoheader --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have autoconf installed to compile $package."
echo "Download the appropriate package for your distribution,"
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
DIE=1
}
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have autoconf installed to compile $package."
echo "Download the appropriate package for your distribution,"
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
DIE=1
}
if test "$DIE" -eq 1; then
exit 1
fi
if test -z "$*"; then
echo "I am going to run ./configure with no arguments - if you wish "
echo "to pass any to it, please specify them on the $0 command line."
fi
echo "Generating configuration files for $package, please wait...."
configure_ac=${etcdir}/configure.ac
configure=${tmpdir}/configure
#echo " aclocal $ACLOCAL_FLAGS"
#aclocal $ACLOCAL_FLAGS
echo " autoheader ${configure_ac}"
autoheader ${configure_ac}
echo " autoconf -o ${configure} ${configure_ac}"
autoconf -o ${configure} ${configure_ac}
${configure} "$@" && echo

View File

@ -0,0 +1 @@
keep me

View File

@ -0,0 +1,185 @@
#-------------------------------------------------------------------------------
# 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/etc/Makefile.in,v $
#
# @configure_input@
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# General command definitions
#-------------------------------------------------------------------------------
MKDIR = mkdir -p
RM = rm -f
RMDIR = rm -rf
DOXYGEN = doxygen
#-------------------------------------------------------------------------------
# Basic directory and file definitions
#-------------------------------------------------------------------------------
BASE_DIR = @builddir@
DOC_DIR = ${BASE_DIR}/doc
DOXYGEN_DIR = ${DOC_DIR}/doxygen
ETC_DIR = ${BASE_DIR}/etc
SRC_DIR = ${BASE_DIR}/src
TMP_DIR = ${BASE_DIR}/tmp
USR_DIR = ${BASE_DIR}/../../usr
USR_INCLUDE_DIR = ${USR_DIR}/include
USR_LIB_DIR = ${USR_DIR}/lib
BOOST_INCLUDE_DIR = ${USR_INCLUDE_DIR}/boost-1_31
LIBXMLPP_INCLUDE_DIR = ${USR_INCLUDE_DIR}/libxml++-1.0
VPATH = ${SRC_DIR}
MODULES_DIR = ${BASE_DIR}/../../modules
CORE_DIR = ${MODULES_DIR}/core
CORE_INCLUDE_DIR = ${CORE_DIR}/include
CORE_LIB_DIR = ${CORE_DIR}/lib
CORE_LIB = livesupport_core
CORE_LIB_FILE = ${CORE_LIB_DIR}/lib${CORE_LIB}.a
DB_DIR = ${MODULES_DIR}/db
DB_INCLUDE_DIR = ${DB_DIR}/include
DB_LIB_DIR = ${DB_DIR}/lib
DB_LIB = livesupport_db
DB_LIB_FILE = ${DB_LIB_DIR}/lib${DB_LIB}.a
STORAGE_DIR = ${MODULES_DIR}/storage
STORAGE_INCLUDE_DIR = ${STORAGE_DIR}/include
STORAGE_LIB_DIR = ${STORAGE_DIR}/lib
STORAGE_LIB = livesupport_storage
STORAGE_LIB_FILE = ${STORAGE_LIB_DIR}/lib${STORAGE_LIB}.a
SCHEDULER_EXE = ${TMP_DIR}/scheduler
TEST_RUNNER = ${TMP_DIR}/testRunner
DOXYGEN_CONFIG = ${ETC_DIR}/doxygen.config
#-------------------------------------------------------------------------------
# Configuration parameters
#-------------------------------------------------------------------------------
CPPFLAGS = @CPPFLAGS@
CXXFLAGS = @CXXFLAGS@ @DEFS@ -pedantic -Wall -Wno-long-long \
-I${USR_INCLUDE_DIR} \
-I${BOOST_INCLUDE_DIR} \
-I${LIBXMLPP_INCLUDE_DIR} \
-I${CORE_INCLUDE_DIR} \
-I${DB_INCLUDE_DIR} \
-I${STORAGE_INCLUDE_DIR} \
-I${TMP_DIR}
LDFLAGS = @LDFLAGS@ -L${USR_LIB_DIR} \
-L${CORE_LIB_DIR} \
-L${DB_LIB_DIR} \
-L${STORAGE_LIB_DIR}
#-------------------------------------------------------------------------------
# Dependencies
#-------------------------------------------------------------------------------
SCHEDULER_OBJS = ${TMP_DIR}/SignalDispatcher.o \
${TMP_DIR}/XmlRpcDaemon.o \
${TMP_DIR}/SchedulerDaemon.o \
${TMP_DIR}/UploadPlaylistMethod.o \
${TMP_DIR}/ScheduleFactory.o \
${TMP_DIR}/PostgresqlSchedule.o
SCHEDULER_EXE_OBJS = ${SCHEDULER_OBJS} \
${TMP_DIR}/main.o
SCHEDULER_EXE_LIBS = -l${STORAGE_LIB} -l${DB_LIB} -l${CORE_LIB} \
-lodbc++ -lboost_date_time-gcc \
-lxmlrpc++ -lssl -lxml++-1.0
TEST_RUNNER_OBJS = ${SCHEDULER_OBJS} \
${TMP_DIR}/SchedulerDaemonTest.o \
${TMP_DIR}/UploadPlaylistMethodTest.o \
${TMP_DIR}/PostgresqlScheduleTest.o \
${TMP_DIR}/TestRunner.o
TEST_RUNNER_LIBS = ${SCHEDULER_EXE_LIBS} -lcppunit -ldl
#-------------------------------------------------------------------------------
# Targets
#-------------------------------------------------------------------------------
.PHONY: all dir_setup doc clean docclean depclean distclean
all: dir_setup ${SCHEDULER_EXE}
dir_setup: ${TMP_DIR} ${DOXYGEN_DIR}
doc:
${DOXYGEN} ${DOXYGEN_CONFIG}
clean:
${RM} ${SCHEDULER_EXE_OBJS} ${SCHEDULER_EXE}
${RM} ${TEST_RUNNER_OBJS} ${TEST_RUNNER}
docclean:
${RMDIR} ${DOXYGEN_DIR}/html
depclean: clean
distclean: clean docclean
${RMDIR} ${TMP_DIR}/config* ${TMP_DIR}/autom4te*
check: all ${TEST_RUNNER}
LD_LIBRARY_PATH=${USR_LIB_DIR} ${TEST_RUNNER}
#-------------------------------------------------------------------------------
# Specific targets
#-------------------------------------------------------------------------------
${SCHEDULER_EXE}: ${CORE_LIB_FILE} ${DB_LIB_FILE} ${STORAGE_LIB_FILE} \
${SCHEDULER_EXE_OBJS}
${CXX} ${LDFLAGS} -o $@ $^ ${SCHEDULER_EXE_LIBS}
${TMP_DIR}:
${MKDIR} ${TMP_DIR}
${DOXYGEN_DIR}:
${MKDIR} ${DOXYGEN_DIR}
${TEST_RUNNER}: ${CORE_LIB_FILE} ${DB_LIB_FILE} ${STORAGE_LIB_FILE} \
${TEST_RUNNER_OBJS}
${CXX} ${LDFLAGS} -o $@ ${TEST_RUNNER_OBJS} ${TEST_RUNNER_LIBS}
${CORE_LIB_FILE}:
${MAKE} -C ${CORE_DIR}
${DB_LIB_FILE}:
${MAKE} -C ${DB_DIR}
${STORAGE_LIB_FILE}:
${MAKE} -C ${STORAGE_DIR}
#-------------------------------------------------------------------------------
# Pattern rules
#-------------------------------------------------------------------------------
${TMP_DIR}/%.o : ${SRC_DIR}/%.cxx
${CXX} ${CPPFLAGS} ${CXXFLAGS} -c -o $@ $<

View File

@ -0,0 +1,49 @@
dnl-----------------------------------------------------------------------------
dnl Copyright (c) 2004 Media Development Loan Fund
dnl
dnl This file is part of the LiveSupport project.
dnl http://livesupport.campware.org/
dnl To report bugs, send an e-mail to bugs@campware.org
dnl
dnl LiveSupport is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
dnl the Free Software Foundation; either version 2 of the License, or
dnl (at your option) any later version.
dnl
dnl LiveSupport is distributed in the hope that it will be useful,
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
dnl GNU General Public License for more details.
dnl
dnl You should have received a copy of the GNU General Public License
dnl along with LiveSupport; if not, write to the Free Software
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 Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/etc/configure.ac,v $
dnl-----------------------------------------------------------------------------
dnl-----------------------------------------------------------------------------
dnl NOTE: Run all configure related scripts from the tmp directory of the
dnl project.
dnl This is due to the fact that configure spreads a lot of trash around,
dnl like atom4te cache directories, config.* files, etc. into the directory
dnl it is being run from. We clearly don't want these in our base directory.
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_CONFIG_SRCDIR(../src/main.cxx)
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_CONFIG_FILES(../Makefile:../etc/Makefile.in)
AC_OUTPUT()

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE connectionManagerFactory [
<!ELEMENT connectionManagerFactory (simpleConnectionManager) >
<!ELEMENT simpleConnectionManager EMPTY >
<!ATTLIST simpleConnectionManager dsn CDATA #REQUIRED >
<!ATTLIST simpleConnectionManager userName CDATA #REQUIRED >
<!ATTLIST simpleConnectionManager password CDATA #REQUIRED >
]>
<connectionManagerFactory>
<simpleConnectionManager dsn = "LiveSupport-test"
userName = "test"
password = "test"
/>
</connectionManagerFactory>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE scheduleFactory [
<!ELEMENT scheduleFactory (postgresqlSchedule) >
<!ELEMENT postgresqlSchedule EMPTY >
]>
<scheduleFactory>
<postgresqlSchedule/>
</scheduleFactory>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE scheduler [
<!ELEMENT scheduler (xmlRpcDaemon) >
<!ELEMENT xmlRpcDaemon EMPTY >
<!ATTLIST xmlRpcDaemon xmlRpcHost CDATA #REQUIRED >
<!ATTLIST xmlRpcDaemon xmlRpcPort NMTOKEN #REQUIRED >
<!ATTLIST xmlRpcDaemon pidFileName CDATA #REQUIRED >
<!ATTLIST xmlRpcDaemon background (true|false) "true" >
]>
<scheduler>
<xmlRpcDaemon xmlRpcHost = "localhost"
xmlRpcPort = "3344"
pidFileName = "tmp/scheduler.pid"
/>
</scheduler>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE storageClientFactory [
<!ELEMENT storageClientFactory (testStorage?) >
<!ELEMENT testStorage (playlist*) >
<!ELEMENT playlist EMPTY >
<!ATTLIST playlist id NMTOKEN #REQUIRED >
<!ATTLIST playlist playlength NMTOKEN #REQUIRED >
]>
<storageClientFactory>
<testStorage>
<playlist id="1" playlength="01:00:00.000"/>
</testStorage>
</storageClientFactory>

View File

@ -0,0 +1,251 @@
/*------------------------------------------------------------------------------
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/PostgresqlSchedule.cxx,v $
------------------------------------------------------------------------------*/
/* ============================================================ include files */
#ifdef HAVE_CONFIG_H
#include "configure.h"
#endif
#include <odbc++/statement.h>
#include <odbc++/preparedstatement.h>
#include <odbc++/resultset.h>
#include "LiveSupport/Db/Conversion.h"
#include "PostgresqlSchedule.h"
using namespace odbc;
using namespace LiveSupport::Core;
using namespace LiveSupport::Db;
using namespace LiveSupport::Scheduler;
/* =================================================== local data structures */
/* ================================================ local constants & macros */
/*------------------------------------------------------------------------------
* The name of the config element for this class
*----------------------------------------------------------------------------*/
const std::string PostgresqlSchedule::configElementNameStr =
"postgresqlSchedule";
/*------------------------------------------------------------------------------
* The SQL create statement, used for installation.
*----------------------------------------------------------------------------*/
const std::string PostgresqlSchedule::createStmt =
"CREATE TABLE schedule\n"
"(\n"
" id INT NOT NULL,\n"
" playlist INT NOT NULL,\n"
" starts TIMESTAMP NOT NULL,\n"
" ends TIMESTAMP NOT NULL,\n"
"\n"
" PRIMARY KEY(id)\n"
");";
/*------------------------------------------------------------------------------
* The SQL create statement, used for installation.
*----------------------------------------------------------------------------*/
const std::string PostgresqlSchedule::dropStmt =
"DROP TABLE schedule;";
/*------------------------------------------------------------------------------
* The SQL statement for querying if a timeframe is available.
* The parameters for this call are: starts, starts, ends, ends, starts, ends,
* and returns the number of items falling into the quieried timeframe.
* Basically checks if the starts or ends value falls within the queried frame
* or starts before and ends after the queried timeframe.
*----------------------------------------------------------------------------*/
const std::string PostgresqlSchedule::isTimeframaAvailableStmt =
"SELECT COUNT(*) FROM schedule WHERE "
"((starts <= ? AND ? < ends) OR (starts < ? AND ? <= ends)) "
"OR (? <= starts AND ends <= ?)";
/*------------------------------------------------------------------------------
* The SQL statement for scheduling a playlist.
* It's a simple insert.
*----------------------------------------------------------------------------*/
const std::string PostgresqlSchedule::schedulePlaylistStmt =
"INSERT INTO schedule(id, playlist, starts, ends) VALUES(?, ?, ?, ?)";
/* =============================================== local function prototypes */
/* ============================================================= module code */
/*------------------------------------------------------------------------------
* Configure the schedule.
*----------------------------------------------------------------------------*/
void
PostgresqlSchedule :: configure(const xmlpp::Element & element)
throw (std::invalid_argument,
std::logic_error)
{
if (element.get_name() != configElementNameStr) {
std::string eMsg = "Bad configuration element ";
eMsg += element.get_name();
throw std::invalid_argument(eMsg);
}
// nothing to do here, really
}
/*------------------------------------------------------------------------------
* Install the PostgresqlSchedule.
*----------------------------------------------------------------------------*/
void
PostgresqlSchedule :: install(void) throw (std::exception)
{
Ptr<Connection>::Ref conn;
try {
conn = cm->getConnection();
Ptr<Statement>::Ref stmt(conn->createStatement());
stmt->execute(createStmt);
cm->returnConnection(conn);
} catch (std::exception &e) {
if (conn) {
cm->returnConnection(conn);
}
throw;
}
}
/*------------------------------------------------------------------------------
* Uninstall the PostgresqlSchedule.
*----------------------------------------------------------------------------*/
void
PostgresqlSchedule :: uninstall(void) throw (std::exception)
{
Ptr<Connection>::Ref conn;
try {
conn = cm->getConnection();
Ptr<Statement>::Ref stmt(conn->createStatement());
stmt->execute(dropStmt);
cm->returnConnection(conn);
} catch (std::exception &e) {
if (conn) {
cm->returnConnection(conn);
}
throw;
}
}
/*------------------------------------------------------------------------------
* Check if a timeframe is available.
*----------------------------------------------------------------------------*/
bool
PostgresqlSchedule :: isTimeframeAvailable(
Ptr<ptime>::Ref from,
Ptr<ptime>::Ref to) throw ()
{
Ptr<Connection>::Ref conn;
bool result = false;
try {
conn = cm->getConnection();
Ptr<Timestamp>::Ref timestamp;
Ptr<PreparedStatement>::Ref pstmt(conn->prepareStatement(
isTimeframaAvailableStmt));
timestamp = Conversion::ptimeToTimestamp(from);
pstmt->setTimestamp(1, *timestamp);
pstmt->setTimestamp(2, *timestamp);
pstmt->setTimestamp(5, *timestamp);
timestamp = Conversion::ptimeToTimestamp(to);
pstmt->setTimestamp(3, *timestamp);
pstmt->setTimestamp(4, *timestamp);
pstmt->setTimestamp(6, *timestamp);
Ptr<ResultSet>::Ref rs(pstmt->executeQuery());
result = (rs->next()) ? (rs->getInt(1) == 0) : false;
cm->returnConnection(conn);
} catch (std::exception &e) {
if (conn) {
cm->returnConnection(conn);
}
return false;
}
return result;
}
/*------------------------------------------------------------------------------
* Schedule a playlist
*----------------------------------------------------------------------------*/
void
PostgresqlSchedule :: schedulePlaylist(
Ptr<Playlist>::Ref playlist,
Ptr<ptime>::Ref playtime)
throw (std::invalid_argument)
{
Ptr<Connection>::Ref conn;
bool result = false;
try {
conn = cm->getConnection();
Ptr<Timestamp>::Ref timestamp;
Ptr<UniqueId>::Ref id;
Ptr<ptime>::Ref ends;
Ptr<PreparedStatement>::Ref pstmt(conn->prepareStatement(
schedulePlaylistStmt));
id = UniqueId::generateId();
pstmt->setInt(1, id->getId());
pstmt->setInt(2, playlist->getId()->getId());
timestamp = Conversion::ptimeToTimestamp(playtime);
pstmt->setTimestamp(3, *timestamp);
ends.reset(new ptime((*playtime) + *(playlist->getPlaylength())));
timestamp = Conversion::ptimeToTimestamp(ends);
pstmt->setTimestamp(4, *timestamp);
result = pstmt->executeUpdate() == 1;
cm->returnConnection(conn);
} catch (std::exception &e) {
if (conn) {
cm->returnConnection(conn);
}
throw std::invalid_argument(e.what());
}
if (!result) {
throw std::invalid_argument("couldn't insert into database");
}
}

View File

@ -0,0 +1,221 @@
/*------------------------------------------------------------------------------
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/PostgresqlSchedule.h,v $
------------------------------------------------------------------------------*/
#ifndef PostresqlSchedule_h
#define PostresqlSchedule_h
#ifndef __cplusplus
#error This is a C++ include file
#endif
/* ============================================================ include files */
#ifdef HAVE_CONFIG_H
#include "configure.h"
#endif
#include <stdexcept>
#include <string>
#include "LiveSupport/Core/Ptr.h"
#include "LiveSupport/Core/Configurable.h"
#include "LiveSupport/Db/ConnectionManagerInterface.h"
#include "ScheduleInterface.h"
namespace LiveSupport {
namespace Scheduler {
using namespace LiveSupport;
using namespace LiveSupport::Core;
/* ================================================================ constants */
/* =================================================================== macros */
/* =============================================================== data types */
/**
* An object containing the schedule of events in a PostreSQL database.
*
* @author $Author: maroy $
* @version $Revision: 1.1 $
*/
class PostgresqlSchedule : public Configurable,
public ScheduleInterface
{
private:
/**
* The name of the configuration XML elmenent used by this object.
*/
static const std::string configElementNameStr;
/**
* The SQL create statement used in the installation step.
*/
static const std::string createStmt;
/**
* The SQL drop statement used in the uninstallation step.
*/
static const std::string dropStmt;
/**
* The SQL statement for querying if a time frame is available.
*/
static const std::string isTimeframaAvailableStmt;
/**
* The SQL statement for scheduling a playlist.
*/
static const std::string schedulePlaylistStmt;
/**
* The database connection manager to use for connecting the
* database.
*/
Ptr<Db::ConnectionManagerInterface>::Ref cm;
/**
* The default constructor.
*/
PostgresqlSchedule(void) throw()
{
}
public:
/**
* Construct a PostgresqlSchedule.
*
* @param cm the connection manager the PostgresqlSchedule will use to
* connect to the database.
*/
PostgresqlSchedule(Ptr<Db::ConnectionManagerInterface>::Ref cm)
throw ()
{
this->cm = cm;
}
/**
* A virtual destructor, as this class has virtual functions.
*/
virtual
~PostgresqlSchedule(void) throw ()
{
}
/**
* 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;
}
/**
* Configure the object based on the XML element supplied.
* The supplied element is expected to be of the name
* returned by configElementName().
*
* @param element the XML element to configure the object from.
* @exception std::invalid_argument if the supplied XML element
* contains bad configuraiton information
* @exception std::logic_error if the object has already
* been configured, and can not be reconfigured.
*/
virtual void
configure(const xmlpp::Element & element)
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);
/**
* Check if a timeframe is available for scheduling.
*
* @param from the start time of the timeframe.
* @param to the end time of the timeframe.
* @return true if the timeframe is available, false otherwise.
*/
virtual bool
isTimeframeAvailable(Ptr<ptime>::Ref from,
Ptr<ptime>::Ref to) throw ();
/**
* Schedule a playlist.
*
* @param playlist the playlist to schedule.
* @param playtime the time to schedule the playlist for.
* @exception std::invalid_argument if the there is something
* already scheduled for the duration of the playlist.
*/
virtual void
schedulePlaylist(Ptr<Playlist>::Ref playlist,
Ptr<ptime>::Ref playtime)
throw (std::invalid_argument);
};
/* ================================================= external data structures */
/* ====================================================== function prototypes */
} // namespace Scheduler
} // namespace LiveSupport
#endif // PostresqlSchedule_h

View File

@ -0,0 +1,228 @@
/*------------------------------------------------------------------------------
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/PostgresqlScheduleTest.cxx,v $
------------------------------------------------------------------------------*/
/* ============================================================ include files */
#ifdef HAVE_CONFIG_H
#include "configure.h"
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#else
#error "Need unistd.h"
#endif
#include <string>
#include <iostream>
#include "LiveSupport/Db/ConnectionManagerFactory.h"
#include "PostgresqlSchedule.h"
#include "PostgresqlScheduleTest.h"
using namespace boost::posix_time;
using namespace LiveSupport::Scheduler;
/* =================================================== local data structures */
/* ================================================ local constants & macros */
CPPUNIT_TEST_SUITE_REGISTRATION(PostgresqlScheduleTest);
/**
* The name of the configuration file for the connection manager factory.
*/
static const std::string configFileName = "etc/connectionManagerFactory.xml";
/* =============================================== local function prototypes */
/* ============================================================= module code */
/*------------------------------------------------------------------------------
* Set up the test environment
*----------------------------------------------------------------------------*/
void
PostgresqlScheduleTest :: setUp(void) throw ()
{
try {
Ptr<xmlpp::DomParser>::Ref parser(
new xmlpp::DomParser(configFileName, true));
const xmlpp::Document * document = parser->get_document();
const xmlpp::Element * root = document->get_root_node();
Ptr<ConnectionManagerFactory>::Ref cmf =
ConnectionManagerFactory::getInstance();
cmf->configure(*root);
cm = cmf->getConnectionManager();
schedule.reset(new PostgresqlSchedule(cm));
schedule->install();
} catch (std::invalid_argument &e) {
CPPUNIT_FAIL("semantic error in configuration file");
} catch (xmlpp::exception &e) {
CPPUNIT_FAIL("error parsing configuration file");
}
}
/*------------------------------------------------------------------------------
* Clean up the test environment
*----------------------------------------------------------------------------*/
void
PostgresqlScheduleTest :: tearDown(void) throw ()
{
schedule->uninstall();
schedule.reset();
cm.reset();
}
/*------------------------------------------------------------------------------
* Test for an available timeframe in an empty schedule database.
*----------------------------------------------------------------------------*/
void
PostgresqlScheduleTest :: firstTest(void)
throw (CPPUNIT_NS::Exception)
{
// check with any two arbitary dates, the timeframe should be available
Ptr<ptime>::Ref from(new ptime(time_from_string("2004-07-23 10:00:00")));
Ptr<ptime>::Ref to(new ptime(time_from_string("2004-07-23 11:00:00")));
CPPUNIT_ASSERT(schedule->isTimeframeAvailable(from, to));
}
/*------------------------------------------------------------------------------
* Schedule a single playlist.
*----------------------------------------------------------------------------*/
void
PostgresqlScheduleTest :: simpleScheduleTest(void)
throw (CPPUNIT_NS::Exception)
{
// create a 1 hour long playlist, from 10 o'clock 2004-07-23
Ptr<UniqueId>::Ref id = UniqueId::generateId();
Ptr<time_duration>::Ref playlength(new time_duration(1, 0, 0));
Ptr<Playlist>::Ref playlist(new Playlist(id, playlength));
Ptr<ptime>::Ref from(new ptime(time_from_string(
"2004-07-23 10:00:00")));
try {
schedule->schedulePlaylist(playlist, from);
} catch (std::invalid_argument &e) {
CPPUNIT_ASSERT(e.what());
}
}
/*------------------------------------------------------------------------------
* Schedule a single playlist, and then query for available timeframes
* around it.
*----------------------------------------------------------------------------*/
void
PostgresqlScheduleTest :: scheduleAndQueryTest(void)
throw (CPPUNIT_NS::Exception)
{
// create a 1 hour long playlist, from 10 o'clock 2004-07-23
Ptr<UniqueId>::Ref id = UniqueId::generateId();
Ptr<time_duration>::Ref playlength(new time_duration(1, 0, 0));
Ptr<Playlist>::Ref playlist(new Playlist(id, playlength));
Ptr<ptime>::Ref from(new ptime(time_from_string(
"2004-07-23 10:00:00")));
try {
schedule->schedulePlaylist(playlist, from);
} catch (std::invalid_argument &e) {
CPPUNIT_ASSERT(e.what());
}
// check for available timeframes around the inserted one
Ptr<ptime>::Ref to;
// this is the exact same timeframe as the scheduled playlist
from.reset(new ptime(time_from_string("2004-07-23 10:00:00")));
to.reset(new ptime(time_from_string("2004-07-23 11:00:00")));
CPPUNIT_ASSERT(!schedule->isTimeframeAvailable(from, to));
// a timeframe before our playlist
from.reset(new ptime(time_from_string("2004-07-23 09:00:00")));
to.reset(new ptime(time_from_string("2004-07-23 09:50:00")));
CPPUNIT_ASSERT(schedule->isTimeframeAvailable(from, to));
// a timeframe after our playlist
from.reset(new ptime(time_from_string("2004-07-23 11:10:00")));
to.reset(new ptime(time_from_string("2004-07-23 12:00:00")));
CPPUNIT_ASSERT(schedule->isTimeframeAvailable(from, to));
// a timeframe inside ours
from.reset(new ptime(time_from_string("2004-07-23 10:10:00")));
to.reset(new ptime(time_from_string("2004-07-23 10:50:00")));
CPPUNIT_ASSERT(!schedule->isTimeframeAvailable(from, to));
// a timeframe encapsulating ours
from.reset(new ptime(time_from_string("2004-07-23 09:50:00")));
to.reset(new ptime(time_from_string("2004-07-23 11:10:00")));
CPPUNIT_ASSERT(!schedule->isTimeframeAvailable(from, to));
// a timeframe starting earlier, but flowing into ours
from.reset(new ptime(time_from_string("2004-07-23 09:00:00")));
to.reset(new ptime(time_from_string("2004-07-23 10:10:00")));
CPPUNIT_ASSERT(!schedule->isTimeframeAvailable(from, to));
// a timeframe starting inside ours, and continuing afterwards
from.reset(new ptime(time_from_string("2004-07-23 10:50:00")));
to.reset(new ptime(time_from_string("2004-07-23 11:50:00")));
CPPUNIT_ASSERT(!schedule->isTimeframeAvailable(from, to));
// a timeframe ending exaclty when ours starts, which is OK
from.reset(new ptime(time_from_string("2004-07-23 09:00:00")));
to.reset(new ptime(time_from_string("2004-07-23 10:00:00")));
CPPUNIT_ASSERT(schedule->isTimeframeAvailable(from, to));
// a timeframe starting exactly when ours ends, which is OK
from.reset(new ptime(time_from_string("2004-07-23 11:00:00")));
to.reset(new ptime(time_from_string("2004-07-23 12:00:00")));
CPPUNIT_ASSERT(schedule->isTimeframeAvailable(from, to));
}

View File

@ -0,0 +1,142 @@
/*------------------------------------------------------------------------------
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/PostgresqlScheduleTest.h,v $
------------------------------------------------------------------------------*/
#ifndef PostgresqlScheduleTest_h
#define PostgresqlScheduleTest_h
#ifndef __cplusplus
#error This is a C++ include file
#endif
/* ============================================================ include files */
#ifdef HAVE_CONFIG_H
#include "configure.h"
#endif
#include <cppunit/extensions/HelperMacros.h>
#include "LiveSupport/Db/ConnectionManagerInterface.h"
namespace LiveSupport {
namespace Scheduler {
using namespace LiveSupport;
using namespace LiveSupport::Db;
using namespace LiveSupport::Core;
/* ================================================================ constants */
/* =================================================================== macros */
/* =============================================================== data types */
/**
* Unit test for the PostgresqlSchedule class.
*
* @author $Author: maroy $
* @version $Revision: 1.1 $
* @see PostgresqlSchedule
*/
class PostgresqlScheduleTest : public CPPUNIT_NS::TestFixture
{
CPPUNIT_TEST_SUITE(PostgresqlScheduleTest);
CPPUNIT_TEST(firstTest);
CPPUNIT_TEST(simpleScheduleTest);
CPPUNIT_TEST(scheduleAndQueryTest);
CPPUNIT_TEST_SUITE_END();
private:
/**
* The connection manager used for testing.
*/
Ptr<ConnectionManagerInterface>::Ref cm;
/**
* The schedule used for testing.
*/
Ptr<PostgresqlSchedule>::Ref schedule;
protected:
/**
* Test for an available timeframe in an empty schedule database.
*
* @exception CPPUNIT_NS::Exception on test failures.
*/
void
firstTest(void) throw (CPPUNIT_NS::Exception);
/**
* Schedule a single playlist.
*
* @exception CPPUNIT_NS::Exception on test failures.
*/
void
simpleScheduleTest(void) throw (CPPUNIT_NS::Exception);
/**
* Schedule a single playlist, and then query for available timeframes
* around it.
*
* @exception CPPUNIT_NS::Exception on test failures.
*/
void
scheduleAndQueryTest(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 // PostgresqlScheduleTest_h

View File

@ -0,0 +1,117 @@
/*------------------------------------------------------------------------------
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/ScheduleFactory.cxx,v $
------------------------------------------------------------------------------*/
/* ============================================================ include files */
#ifdef HAVE_CONFIG_H
#include "configure.h"
#endif
#include "LiveSupport/Db/ConnectionManagerFactory.h"
#include "PostgresqlSchedule.h"
#include "ScheduleFactory.h"
using namespace LiveSupport::Core;
using namespace LiveSupport::Db;
using namespace LiveSupport::Scheduler;
/* =================================================== local data structures */
/* ================================================ local constants & macros */
/*------------------------------------------------------------------------------
* The name of the config element for this class
*----------------------------------------------------------------------------*/
const std::string ScheduleFactory::configElementNameStr =
"scheduleFactory";
/*------------------------------------------------------------------------------
* The singleton instance of Scheduleactory
*----------------------------------------------------------------------------*/
Ptr<ScheduleFactory>::Ref ScheduleFactory::singleton;
/* =============================================== local function prototypes */
/* ============================================================= module code */
/*------------------------------------------------------------------------------
* Return the singleton instance to ScheduleFactory
*----------------------------------------------------------------------------*/
Ptr<ScheduleFactory>::Ref
ScheduleFactory :: getInstance(void) throw ()
{
if (!singleton.get()) {
singleton.reset(new ScheduleFactory());
}
return singleton;
}
/*------------------------------------------------------------------------------
* Configure the schedule factory.
*----------------------------------------------------------------------------*/
void
ScheduleFactory :: configure(const xmlpp::Element & element)
throw (std::invalid_argument,
std::logic_error)
{
if (element.get_name() != configElementNameStr) {
std::string eMsg = "Bad configuration element ";
eMsg += element.get_name();
throw std::invalid_argument(eMsg);
}
schedule.reset();
Ptr<ConnectionManagerFactory>::Ref cmf =
ConnectionManagerFactory::getInstance();
Ptr<ConnectionManagerInterface>::Ref cm = cmf->getConnectionManager();
// try to look for a PostgresqlSchedule configuration element
xmlpp::Node::NodeList nodes =
element.get_children(PostgresqlSchedule::getConfigElementName());
if (nodes.size() >= 1) {
const xmlpp::Element * configElement =
dynamic_cast<const xmlpp::Element*> (*(nodes.begin()));
Ptr<PostgresqlSchedule>::Ref dbs(new PostgresqlSchedule(cm));
dbs->configure(*configElement);
schedule = dbs;
}
if (!schedule) {
throw std::invalid_argument("no storage client factories to configure");
}
}

View File

@ -0,0 +1,163 @@
/*------------------------------------------------------------------------------
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/ScheduleFactory.h,v $
------------------------------------------------------------------------------*/
#ifndef ScheduleFactory_h
#define ScheduleFactory_h
#ifndef __cplusplus
#error This is a C++ include file
#endif
/* ============================================================ include files */
#ifdef HAVE_CONFIG_H
#include "configure.h"
#endif
#include <stdexcept>
#include "LiveSupport/Core/Configurable.h"
#include "ScheduleInterface.h"
namespace LiveSupport {
namespace Scheduler {
using namespace LiveSupport;
using namespace LiveSupport::Core;
/* ================================================================ constants */
/* =================================================================== macros */
/* =============================================================== data types */
/**
* The factory to create appropriate Schedule objects.
*
* @author $Author: maroy $
* @version $Revision: 1.1 $
*/
class ScheduleFactory :
virtual public Configurable
{
private:
/**
* The name of the configuration XML elmenent used by this object.
*/
static const std::string configElementNameStr;
/**
* The singleton instance of this object.
*/
static Ptr<ScheduleFactory>::Ref singleton;
/**
* The schedule created by this factory.
*/
Ptr<ScheduleInterface>::Ref schedule;
/**
* The default constructor.
*/
ScheduleFactory(void) throw()
{
}
public:
/**
* A virtual destructor, as this class has virtual functions.
*/
virtual
~ScheduleFactory(void) throw ()
{
}
/**
* 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
configElementName(void) throw ()
{
return configElementNameStr;
}
/**
* Returns the singleton instance of this object.
*
* @return the singleton instance of this object.
*/
static Ptr<ScheduleFactory>::Ref
getInstance() throw ();
/**
* Configure the object based on the XML element supplied.
*
* @param element the XML element to configure the object from.
* @exception std::invalid_argument if the supplied XML element
* contains bad configuraiton information
* @exception std::logic_error if the object has already
* been configured, and can not be reconfigured.
*/
virtual void
configure(const xmlpp::Element & element)
throw (std::invalid_argument,
std::logic_error);
/**
* Return a schedule.
*
* @return the appropriate schedule, according to the
* configuration of this factory.
*/
Ptr<ScheduleInterface>::Ref
getSchedule(void) throw ()
{
return schedule;
}
};
/* ================================================= external data structures */
/* ====================================================== function prototypes */
} // namespace Storage
} // namespace LiveSupport
#endif // ScheduleFactory_h

View File

@ -0,0 +1,115 @@
/*------------------------------------------------------------------------------
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/ScheduleInterface.h,v $
------------------------------------------------------------------------------*/
#ifndef ScheduleInterface_h
#define ScheduleInterface_h
#ifndef __cplusplus
#error This is a C++ include file
#endif
/* ============================================================ include files */
#ifdef HAVE_CONFIG_H
#include "configure.h"
#endif
#include <stdexcept>
#include <boost/date_time/posix_time/posix_time.hpp>
#include "LiveSupport/Core/Ptr.h"
#include "LiveSupport/Core/Installable.h"
#include "LiveSupport/Core/Playlist.h"
namespace LiveSupport {
namespace Scheduler {
using namespace boost::posix_time;
using namespace LiveSupport;
using namespace LiveSupport::Core;
/* ================================================================ constants */
/* =================================================================== macros */
/* =============================================================== data types */
/**
* The generic interface for the component scheduling events.
*
* @author $Author: maroy $
* @version $Revision: 1.1 $
*/
class ScheduleInterface : virtual public Installable
{
public:
/**
* Check if a timeframe is available for scheduling.
*
* @param from the start time of the timeframe.
* @param to the end time of the timeframe.
* @return true if the timeframe is available, false otherwise.
*/
virtual bool
isTimeframeAvailable(Ptr<ptime>::Ref from,
Ptr<ptime>::Ref to) throw ()
= 0;
/**
* Schedule a playlist.
*
* @param playlist the playlist to schedule.
* @param playtime the time to schedule the playlist for.
* @exception std::invalid_argument if the there is something
* already scheduled for the duration of the playlist.
*/
virtual void
schedulePlaylist(Ptr<Playlist>::Ref playlist,
Ptr<ptime>::Ref playtime)
throw (std::invalid_argument)
= 0;
};
/* ================================================= external data structures */
/* ====================================================== function prototypes */
} // namespace Scheduler
} // namespace LiveSupport
#endif // ScheduleInterface_h

View File

@ -0,0 +1,119 @@
/*------------------------------------------------------------------------------
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/SchedulerDaemon.cxx,v $
------------------------------------------------------------------------------*/
/* ============================================================ include files */
#ifdef HAVE_CONFIG_H
#include "configure.h"
#endif
#if HAVE_SIGNAL_H
#include <signal.h>
#else
#error "Need signal.h"
#endif
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#else
#error "Need sys/stat.h"
#endif
#include <iostream>
#include <sstream>
#include <fstream>
#include <cstdio>
#include "SchedulerDaemon.h"
using namespace LiveSupport::Scheduler;
/* =================================================== local data structures */
/* ================================================ local constants & macros */
/**
* The singleton instance of the Scheduler daemon object.
*/
SchedulerDaemon * SchedulerDaemon::schedulerDaemon = 0;
/**
* The name of the XML configuration element for the Scheduler daemon.
*/
static const std::string confElement = "scheduler";
/**
* The name of the XML configuration element for the XmlRpcDaemon inside.
*/
static const std::string xmlRpcDaemonConfElement = "xmlRpcDaemon";
/* =============================================== local function prototypes */
/* ============================================================= module code */
/*------------------------------------------------------------------------------
* Return the singleton instnace.
*----------------------------------------------------------------------------*/
class SchedulerDaemon *
SchedulerDaemon :: getInstance (void) throw ()
{
if (!schedulerDaemon) {
schedulerDaemon = new SchedulerDaemon();
}
return schedulerDaemon;
}
/*------------------------------------------------------------------------------
* Configure the scheduler daemon
*----------------------------------------------------------------------------*/
void
SchedulerDaemon :: configure(const xmlpp::Element & element)
throw (std::invalid_argument,
std::logic_error)
{
if (element.get_name() != confElement) {
std::string eMsg = "Bad configuration element ";
eMsg += element.get_name();
throw std::invalid_argument(eMsg);
}
xmlpp::Node::NodeList nodes =
element.get_children(xmlRpcDaemonConfElement);
if (nodes.size() < 1) {
throw std::invalid_argument("no xmlRpcDaemon element");
}
configureXmlRpcDaemon( *((const xmlpp::Element*) *(nodes.begin())) );
}

View File

@ -0,0 +1,149 @@
/*------------------------------------------------------------------------------
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/SchedulerDaemon.h,v $
------------------------------------------------------------------------------*/
#ifndef SchedulerDaemon_h
#define SchedulerDaemon_h
#ifndef __cplusplus
#error This is a C++ include file
#endif
/* ============================================================ include files */
#ifdef HAVE_CONFIG_H
#include "configure.h"
#endif
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#else
#error "Need sys/types.h"
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#else
#error "Need unistd.h"
#endif
#include <string>
#include <stdexcept>
#include <libxml++/libxml++.h>
#include <XmlRpc.h>
#include "XmlRpcDaemon.h"
namespace LiveSupport {
namespace Scheduler {
/* ================================================================ constants */
/* =================================================================== macros */
/* =============================================================== data types */
/**
* Scheduler daemon main class.
* This class is responsible for starting, running and stopping the
* Scheduler daemon.
*
* @author $Author: maroy $
* @version $Revision: 1.1 $
*/
class SchedulerDaemon : public XmlRpcDaemon
{
private:
/**
* The singleton instance of the scheduler daemon.
*/
static SchedulerDaemon * schedulerDaemon;
/**
* Default constructor.
*/
SchedulerDaemon (void) throw ()
: XmlRpcDaemon()
{
}
protected:
/**
* Register your XML-RPC functions by implementing this function.
*/
virtual void
registerXmlRpcFunctions(XmlRpc::XmlRpcServer & xmlRpcServer)
throw (std::logic_error)
{
}
public:
/**
* Return a pointer to the singleton instance of SchedulerDaemon.
*
* @return a pointer to the singleton instance of SchedulerDaemon
*/
static SchedulerDaemon *
getInstance (void) throw ();
/**
* Configure the scheduler daemon based on the XML element
* supplied.
*
* @param element the XML element to configure the scheduler
* daemon from.
* @exception std::invalid_argument if the supplied XML element
* contains bad configuraiton information
* @exception std::logic_error if the scheduler daemon has already
* been configured.
*/
void
configure(const xmlpp::Element & element)
throw (std::invalid_argument,
std::logic_error);
};
/* ================================================= external data structures */
/* ====================================================== function prototypes */
} // namespace Scheduler
} // namespace LiveSupport
#endif // SchedulerDaemon_h

View File

@ -0,0 +1,129 @@
/*------------------------------------------------------------------------------
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/SchedulerDaemonTest.cxx,v $
------------------------------------------------------------------------------*/
/* ============================================================ include files */
#ifdef HAVE_CONFIG_H
#include "configure.h"
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#else
#error "Need unistd.h"
#endif
#include <string>
#include "SchedulerDaemon.h"
#include "SchedulerDaemonTest.h"
using namespace LiveSupport::Scheduler;
/* =================================================== local data structures */
/* ================================================ local constants & macros */
//CPPUNIT_TEST_SUITE_REGISTRATION(SchedulerDaemonTest);
/**
* 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
SchedulerDaemonTest :: setUp(void) throw ()
{
SchedulerDaemon * daemon = SchedulerDaemon::getInstance();
if (!daemon->isConfigured()) {
try {
std::auto_ptr<xmlpp::DomParser>
parser(new xmlpp::DomParser(configFileName, true));
const xmlpp::Document * document = parser->get_document();
daemon->configure(*(document->get_root_node()));
} catch (std::invalid_argument &e) {
CPPUNIT_FAIL("semantic error in configuration file");
} catch (xmlpp::exception &e) {
CPPUNIT_FAIL("error parsing configuration file");
}
}
}
/*------------------------------------------------------------------------------
* Clean up the test environment
*----------------------------------------------------------------------------*/
void
SchedulerDaemonTest :: tearDown(void) throw ()
{
}
/*------------------------------------------------------------------------------
* Test to see if the singleton Hello object is accessible
*----------------------------------------------------------------------------*/
void
SchedulerDaemonTest :: getSingleton(void) throw (CPPUNIT_NS::Exception)
{
CPPUNIT_ASSERT( SchedulerDaemon::getInstance() );
}
/*------------------------------------------------------------------------------
* Test to see if the scheduler starts and stops OK
*----------------------------------------------------------------------------*/
void
SchedulerDaemonTest :: testStartStop(void) throw (CPPUNIT_NS::Exception)
{
SchedulerDaemon * daemon = SchedulerDaemon::getInstance();
CPPUNIT_ASSERT( daemon );
CPPUNIT_ASSERT( !(daemon->isRunning()) );
daemon->start();
sleep(3);
CPPUNIT_ASSERT( daemon->isRunning() );
daemon->stop();
sleep(3);
CPPUNIT_ASSERT( !(daemon->isRunning()) );
}

View File

@ -0,0 +1,117 @@
/*------------------------------------------------------------------------------
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/SchedulerDaemonTest.h,v $
------------------------------------------------------------------------------*/
#ifndef SchedulerDaemonTest_h
#define SchedulerDaemonTest_h
#ifndef __cplusplus
#error This is a C++ include file
#endif
/* ============================================================ include files */
#ifdef HAVE_CONFIG_H
#include "configure.h"
#endif
#include <cppunit/extensions/HelperMacros.h>
namespace LiveSupport {
namespace Scheduler {
using namespace LiveSupport;
/* ================================================================ constants */
/* =================================================================== macros */
/* =============================================================== data types */
/**
* Unit test for the SchedulerDaemon class.
*
* @author $Author: maroy $
* @version $Revision: 1.1 $
* @see SchedulerDaemon
*/
class SchedulerDaemonTest : public CPPUNIT_NS::TestFixture
{
CPPUNIT_TEST_SUITE(SchedulerDaemonTest);
CPPUNIT_TEST(getSingleton);
CPPUNIT_TEST(testStartStop);
CPPUNIT_TEST_SUITE_END();
protected:
/**
* A simple test to see if the singleton Hello object is accessible.
*
* @exception CPPUNIT_NS::Exception on test failures.
*/
void
getSingleton(void) throw (CPPUNIT_NS::Exception);
/**
* Test to see if the daemon starts an stops OK.
*
* @exception CPPUNIT_NS::Exception on test failures.
*/
void
testStartStop(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 // SchedulerDaemonTest_h

View File

@ -0,0 +1,142 @@
/*------------------------------------------------------------------------------
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/SignalDispatcher.cxx,v $
------------------------------------------------------------------------------*/
/* ============================================================ include files */
#ifdef HAVE_CONFIG_H
#include "configure.h"
#endif
#if HAVE_SIGNAL_H
#include <signal.h>
#else
#error "Need signal.h"
#endif
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#else
#error "Need sys/stat.h"
#endif
#include <iostream>
#include <sstream>
#include <fstream>
#include <cstdio>
#include "SignalDispatcher.h"
using namespace LiveSupport::Scheduler;
/* =================================================== local data structures */
/* ================================================ local constants & macros */
/*------------------------------------------------------------------------------
* The singleton isntnace of SignalDispatcher.
*----------------------------------------------------------------------------*/
SignalDispatcher * SignalDispatcher::instance = 0;
/*------------------------------------------------------------------------------
* The signal handlers.
*----------------------------------------------------------------------------*/
SignalHandler * SignalDispatcher::handlers[NSIG];
/* =============================================== local function prototypes */
/* ============================================================= module code */
/*------------------------------------------------------------------------------
* Return the singleton instnace.
*----------------------------------------------------------------------------*/
class SignalDispatcher *
SignalDispatcher :: getInstance (void) throw ()
{
if (!instance) {
instance = new SignalDispatcher();
}
return instance;
}
/*------------------------------------------------------------------------------
* Register a signal handler
*----------------------------------------------------------------------------*/
void
SignalDispatcher :: registerHandler(
int signal,
SignalHandler * signalHandler)
throw (std::invalid_argument)
{
if (signal < 0 || signal >= NSIG) {
throw std::invalid_argument("invalid signal value");
}
if (!signalHandler) {
throw std::invalid_argument("signalHandler is 0");
}
handlers[signal] = signalHandler;
// register our dispatcher for this signal
::signal(signal, dispatcher);
}
/*------------------------------------------------------------------------------
* Remove a signal handler
*----------------------------------------------------------------------------*/
void
SignalDispatcher :: removeHandler(
int signal)
throw (std::invalid_argument)
{
if (signal < 0 || signal >= NSIG) {
throw std::invalid_argument("invalid signal value");
}
handlers[signal] = 0;
::signal(signal, SIG_DFL);
}
/*------------------------------------------------------------------------------
* Our signal dispatcher
*----------------------------------------------------------------------------*/
void
SignalDispatcher :: dispatcher(int signal) throw ()
{
handlers[signal]->handleSignal(signal);
}

View File

@ -0,0 +1,148 @@
/*------------------------------------------------------------------------------
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/SignalDispatcher.h,v $
------------------------------------------------------------------------------*/
#ifndef SignalDispatcher_h
#define SignalDispatcher_h
#ifndef __cplusplus
#error This is a C++ include file
#endif
/* ============================================================ include files */
#ifdef HAVE_CONFIG_H
#include "configure.h"
#endif
#if HAVE_SIGNAL_H
#include <signal.h>
#else
#error "Need signal.h"
#endif
#include <string>
#include <stdexcept>
#include "SignalHandler.h"
namespace LiveSupport {
namespace Scheduler {
/* ================================================================ constants */
/* =================================================================== macros */
/* =============================================================== data types */
/**
* A class to dispatch signals.
* See http://www.cs.wustl.edu/~schmidt/signal-patterns.html for details.
*
* @author $Author: maroy $
* @version $Revision: 1.1 $
*/
class SignalDispatcher
{
private:
/**
* The singleton instance of this class.
*/
static SignalDispatcher * instance;
/**
* An array of registered signal handlers,
* of size NSIG defined in signal.h
*/
static SignalHandler * handlers[NSIG];
/**
* Default constructor.
*/
SignalDispatcher(void) throw ()
{
}
/**
* The function registered to handle signals.
*
* @param signal the signal being handled.
*/
static void
dispatcher(int signal) throw ();
public:
/**
* Return the singleton instance of SignalDispatcher.
*
* @return the singleton instance of SignalDispatcher.
*/
static SignalDispatcher *
getInstance(void) throw ();
/**
* Register a signal handler for a specific signal.
*
* @param signal the signal to register for.
* @param signalHandler the signal handler to register.
* @exception std::invalid_argument if signal is out of range,
* or if signalHandler is 0.
*/
void
registerHandler(int signal,
SignalHandler * signalHandler)
throw (std::invalid_argument);
/**
* Remove a signal handler for a specific signal.
* Restores the original system signal handling.
*
* @param signal the signal to remove the handler for.
* @exception std::invalid_argument if signal is out of range.
*/
void
removeHandler(int signal) throw (std::invalid_argument);
};
/* ================================================= external data structures */
/* ====================================================== function prototypes */
} // namespace Scheduler
} // namespace LiveSupport
#endif // SignalDispatcher_h

View File

@ -0,0 +1,87 @@
/*------------------------------------------------------------------------------
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/SignalHandler.h,v $
------------------------------------------------------------------------------*/
#ifndef SignalHandler_h
#define SignalHandler_h
#ifndef __cplusplus
#error This is a C++ include file
#endif
/* ============================================================ include files */
#ifdef HAVE_CONFIG_H
#include "configure.h"
#endif
namespace LiveSupport {
namespace Scheduler {
/* ================================================================ constants */
/* =================================================================== macros */
/* =============================================================== data types */
/**
* A class to handle a signal.
* Register subclasses of this class at SignalDispatcher.
* See http://www.cs.wustl.edu/~schmidt/signal-patterns.html for details.
*
* @author $Author: maroy $
* @version $Revision: 1.1 $
* @see SignalDispatcher
*/
class SignalHandler
{
public:
/**
* Handle the signal.
*
* @param signal the actual signal received.
*/
virtual void
handleSignal(int signal) throw () = 0;
};
/* ================================================= external data structures */
/* ====================================================== function prototypes */
} // namespace Scheduler
} // namespace LiveSupport
#endif // SignalHandler_h

View File

@ -0,0 +1,85 @@
/*------------------------------------------------------------------------------
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/TestRunner.cxx,v $
------------------------------------------------------------------------------*/
/* ============================================================ include files */
#ifdef HAVE_CONFIG_H
#include "configure.h"
#endif
#include <cppunit/BriefTestProgressListener.h>
#include <cppunit/CompilerOutputter.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/TestResult.h>
#include <cppunit/TestResultCollector.h>
#include <cppunit/TestRunner.h>
/* =================================================== local data structures */
/* ================================================ local constants & macros */
/* =============================================== local function prototypes */
/* ============================================================= module code */
/*------------------------------------------------------------------------------
* Run all tests
*----------------------------------------------------------------------------*/
int
main( int argc,
char * argv[] ) throw ()
{
// Create the event manager and test controller
CPPUNIT_NS::TestResult controller;
// Add a listener that colllects test result
CPPUNIT_NS::TestResultCollector result;
controller.addListener( &result );
// Add a listener that print dots as test run.
CPPUNIT_NS::BriefTestProgressListener progress;
controller.addListener( &progress );
// Add the top suite to the test runner
CPPUNIT_NS::TestRunner runner;
runner.addTest( CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest() );
runner.run( controller );
// Print test in a compiler compatible format.
CPPUNIT_NS::CompilerOutputter outputter( &result, std::cerr );
outputter.setLocationFormat("%p:%l:");
outputter.write();
return result.wasSuccessful() ? 0 : 1;
}

View File

@ -0,0 +1,183 @@
/*------------------------------------------------------------------------------
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/UploadPlaylistMethod.cxx,v $
------------------------------------------------------------------------------*/
/* ============================================================ include files */
#ifdef HAVE_CONFIG_H
#include "configure.h"
#endif
#ifdef HAVE_TIME_H
#include <time.h>
#else
#error need time.h
#endif
#include <string>
#include "LiveSupport/Core/StorageClientInterface.h"
#include "LiveSupport/Storage/StorageClientFactory.h"
#include "ScheduleInterface.h"
#include "ScheduleFactory.h"
#include "UploadPlaylistMethod.h"
using namespace boost::posix_time;
using namespace LiveSupport;
using namespace LiveSupport::Core;
using namespace LiveSupport::Storage;
using namespace LiveSupport::Scheduler;
/* =================================================== local data structures */
/* ================================================ local constants & macros */
/*------------------------------------------------------------------------------
* The name of this XML-RPC method.
*----------------------------------------------------------------------------*/
const std::string UploadPlaylistMethod::methodName = "stop";
/*------------------------------------------------------------------------------
* The name of the playlist id member in the XML-RPC parameter
* structure.
*----------------------------------------------------------------------------*/
const std::string UploadPlaylistMethod::playlistIdName = "playlistId";
/*------------------------------------------------------------------------------
* The name of the playlength member in the XML-RPC parameter
* structure.
*----------------------------------------------------------------------------*/
const std::string UploadPlaylistMethod::playlengthName = "playlength";
/* =============================================== local function prototypes */
/* ============================================================= module code */
/*------------------------------------------------------------------------------
* Construct the StopXmlRpcMethod and register it right away.
*----------------------------------------------------------------------------*/
UploadPlaylistMethod :: UploadPlaylistMethod (
Ptr<XmlRpc::XmlRpcServer>::Ref xmlRpcServer) throw()
: XmlRpc::XmlRpcServerMethod(methodName, xmlRpcServer.get())
{
}
/*------------------------------------------------------------------------------
* Extract the UniqueId from an XML-RPC function call parameter
*----------------------------------------------------------------------------*/
Ptr<UniqueId>::Ref
UploadPlaylistMethod :: extractPlaylistId(
XmlRpc::XmlRpcValue & xmlRpcValue)
throw (std::invalid_argument)
{
if (!xmlRpcValue.hasMember(playlistIdName)) {
throw std::invalid_argument("no playlist id in parameter structure");
}
Ptr<UniqueId>::Ref id(new UniqueId((int) xmlRpcValue[playlistIdName]));
return id;
}
/*------------------------------------------------------------------------------
* Extract the playtime from an XML-RPC function call parameter
*----------------------------------------------------------------------------*/
Ptr<ptime>::Ref
UploadPlaylistMethod :: extractPlayschedule(
XmlRpc::XmlRpcValue & xmlRpcValue)
throw (std::invalid_argument)
{
if (!xmlRpcValue.hasMember(playlengthName)) {
throw std::invalid_argument("no playlength in parameter structure");
}
struct tm & tm = (struct tm &) xmlRpcValue[playlengthName];
time_t time = mktime(&tm);
Ptr<ptime>::Ref ptime(new ptime(from_time_t(time)));
return ptime;
}
/*------------------------------------------------------------------------------
* Execute the stop XML-RPC function call.
*----------------------------------------------------------------------------*/
void
UploadPlaylistMethod :: execute( XmlRpc::XmlRpcValue & parameters,
XmlRpc::XmlRpcValue & returnValue)
throw ()
{
try {
Ptr<UniqueId>::Ref id = extractPlaylistId(parameters);
Ptr<ptime>::Ref playschedule = extractPlayschedule(parameters);
Ptr<StorageClientFactory>::Ref scf;
Ptr<StorageClientInterface>::Ref storage;
scf = StorageClientFactory::getInstance();
storage = scf->getStorageClient();
if (!storage->existsPlaylist(id)) {
// TODO: mark error
returnValue = XmlRpc::XmlRpcValue(false);
return;
}
Ptr<Playlist>::Ref playlist = storage->getPlaylist(id);
Ptr<ptime>::Ref until(new ptime(*playschedule
+ *(playlist->getPlaylength())));
Ptr<ScheduleFactory>::Ref sf = ScheduleFactory::getInstance();
Ptr<ScheduleInterface>::Ref schedule = sf->getSchedule();
if (!schedule->isTimeframeAvailable(playschedule, until)) {
// TODO: mark error;
returnValue = XmlRpc::XmlRpcValue(false);
return;
}
schedule->schedulePlaylist(playlist, playschedule);
} catch (std::invalid_argument &e) {
// TODO: mark error
returnValue = XmlRpc::XmlRpcValue(false);
return;
}
// TODO
returnValue = XmlRpc::XmlRpcValue(true);
}

View File

@ -0,0 +1,160 @@
/*------------------------------------------------------------------------------
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/UploadPlaylistMethod.h,v $
------------------------------------------------------------------------------*/
#ifndef UploadPlaylistMetohd_h
#define UploadPlaylistMethod_h
#ifndef __cplusplus
#error This is a C++ include file
#endif
/* ============================================================ include files */
#ifdef HAVE_CONFIG_H
#include "configure.h"
#endif
#include <stdexcept>
#include <string>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <XmlRpcServerMethod.h>
#include <XmlRpcValue.h>
#include "LiveSupport/Core/Ptr.h"
#include "LiveSupport/Core/UniqueId.h"
namespace LiveSupport {
namespace Scheduler {
using namespace LiveSupport;
using namespace LiveSupport::Core;
/* ================================================================ constants */
/* =================================================================== macros */
/* =============================================================== data types */
/**
* An XML-RPC method object to accept a playlist for upload,
* and schedule it in the scheduler.
*
* @author $Author: maroy $
* @version $Revision: 1.1 $
*/
class UploadPlaylistMethod : public XmlRpc::XmlRpcServerMethod
{
private:
/**
* The name of this method, as it will be registered into the
* XML-RPC server.
*/
static const std::string methodName;
/**
* The name of the playlist id member in the XML-RPC parameter
* structure.
*/
static const std::string playlistIdName;
/**
* The name of the playlength member in the XML-RPC parameter
* structure.
*/
static const std::string playlengthName;
/**
* Extract the playlist id from the XML-RPC parameters.
*
* @param xmlRpcValue the XML-RPC parameter to extract from.
* @return a UniqueId that was found in the XML-RPC parameter.
* @exception std::invalid_argument if there was no UniqueId
* in xmlRpcValue
*/
Ptr<UniqueId>::Ref
extractPlaylistId(XmlRpc::XmlRpcValue & xmlRpcValue)
throw (std::invalid_argument);
/**
* Extract the playtime from the XML-RPC parameters.
*
* @param xmlRpcValue the XML-RPC parameter to extract from.
* @return the playing time, as stored in the XML-RPC parameter
* @exception std::invalid_argument if there was no playtime
* in xmlRpcValue
*/
Ptr<boost::posix_time::ptime>::Ref
extractPlayschedule(XmlRpc::XmlRpcValue & xmlRpcValue)
throw (std::invalid_argument);
public:
/**
* A default constructor, for testing purposes.
*/
UploadPlaylistMethod(void) throw ()
: XmlRpc::XmlRpcServerMethod(methodName)
{
}
/**
* Constuctor that registers the method with the server right away.
*
* @param xmlRpcServer the XML-RPC server to register with.
*/
UploadPlaylistMethod(
Ptr<XmlRpc::XmlRpcServer>::Ref xmlRpcServer)
throw ();
/**
* Execute the upload playlist command on the Scheduler daemon.
*
* @param parameters XML-RPC function call parameters
* @param returnValue the return value of the call (out parameter)
*/
void
execute( XmlRpc::XmlRpcValue & parameters,
XmlRpc::XmlRpcValue & returnValue) throw ();
};
/* ================================================= external data structures */
/* ====================================================== function prototypes */
} // namespace Scheduler
} // namespace LiveSupport
#endif // UploadPlaylistMetohd_h

View File

@ -0,0 +1,214 @@
/*------------------------------------------------------------------------------
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/UploadPlaylistMethodTest.cxx,v $
------------------------------------------------------------------------------*/
/* ============================================================ include files */
#ifdef HAVE_CONFIG_H
#include "configure.h"
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#else
#error "Need unistd.h"
#endif
#include <string>
#include <iostream>
#include <XmlRpcValue.h>
#include "LiveSupport/Db/ConnectionManagerFactory.h"
#include "LiveSupport/Storage/StorageClientFactory.h"
#include "ScheduleFactory.h"
#include "UploadPlaylistMethod.h"
#include "UploadPlaylistMethodTest.h"
using namespace LiveSupport::Db;
using namespace LiveSupport::Storage;
using namespace LiveSupport::Scheduler;
/* =================================================== local data structures */
/* ================================================ local constants & macros */
CPPUNIT_TEST_SUITE_REGISTRATION(UploadPlaylistMethodTest);
/**
* The name of the configuration file for the storage client factory.
*/
const std::string UploadPlaylistMethodTest::storageClientConfig =
"etc/storageClient.xml";
/**
* The name of the configuration file for the connection manager factory.
*/
const std::string UploadPlaylistMethodTest::connectionManagerConfig =
"etc/connectionManagerFactory.xml";
/**
* The name of the configuration file for the schedule factory.
*/
const std::string UploadPlaylistMethodTest::scheduleConfig =
"etc/scheduleFactory.xml";
/* =============================================== local function prototypes */
/* ============================================================= module code */
/*------------------------------------------------------------------------------
* Configure a Configurable with an XML file.
*----------------------------------------------------------------------------*/
void
UploadPlaylistMethodTest :: configure(
Ptr<Configurable>::Ref configurable,
const std::string fileName)
throw (std::invalid_argument,
xmlpp::exception)
{
Ptr<xmlpp::DomParser>::Ref parser(new xmlpp::DomParser(fileName, true));
const xmlpp::Document * document = parser->get_document();
const xmlpp::Element * root = document->get_root_node();
configurable->configure(*root);
}
/*------------------------------------------------------------------------------
* Set up the test environment
*----------------------------------------------------------------------------*/
void
UploadPlaylistMethodTest :: setUp(void) throw ()
{
try {
Ptr<StorageClientFactory>::Ref scf
= StorageClientFactory::getInstance();
configure(scf, storageClientConfig);
Ptr<ConnectionManagerFactory>::Ref cmf
= ConnectionManagerFactory::getInstance();
configure(cmf, connectionManagerConfig);
Ptr<ScheduleFactory>::Ref sf = ScheduleFactory::getInstance();
configure(sf, scheduleConfig);
schedule = sf->getSchedule();
schedule->install();
} catch (std::invalid_argument &e) {
CPPUNIT_FAIL("semantic error in configuration file");
} catch (xmlpp::exception &e) {
CPPUNIT_FAIL("error parsing configuration file");
} catch (std::exception &e) {
CPPUNIT_FAIL(e.what());
}
}
/*------------------------------------------------------------------------------
* Clean up the test environment
*----------------------------------------------------------------------------*/
void
UploadPlaylistMethodTest :: tearDown(void) throw ()
{
schedule->uninstall();
}
/*------------------------------------------------------------------------------
* Test to see if the singleton Hello object is accessible
*----------------------------------------------------------------------------*/
void
UploadPlaylistMethodTest :: firstTest(void)
throw (CPPUNIT_NS::Exception)
{
Ptr<UploadPlaylistMethod>::Ref method(new UploadPlaylistMethod());
XmlRpc::XmlRpcValue parameters;
XmlRpc::XmlRpcValue result;
struct tm time;
// 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;
method->execute(parameters, result);
CPPUNIT_ASSERT(result);
}
/*------------------------------------------------------------------------------
* Try to upload overlapping playlists, and see them fail.
*----------------------------------------------------------------------------*/
void
UploadPlaylistMethodTest :: overlappingPlaylists(void)
throw (CPPUNIT_NS::Exception)
{
Ptr<UploadPlaylistMethod>::Ref method(new UploadPlaylistMethod());
XmlRpc::XmlRpcValue parameters;
XmlRpc::XmlRpcValue result;
struct tm time;
// 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;
method->execute(parameters, 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;
method->execute(parameters, 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;
method->execute(parameters, 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;
method->execute(parameters, result);
CPPUNIT_ASSERT(!result);
}

View File

@ -0,0 +1,154 @@
/*------------------------------------------------------------------------------
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/UploadPlaylistMethodTest.h,v $
------------------------------------------------------------------------------*/
#ifndef UploadPlaylistMethodTest_h
#define UploadPlaylistMethodTest_h
#ifndef __cplusplus
#error This is a C++ include file
#endif
/* ============================================================ include files */
#ifdef HAVE_CONFIG_H
#include "configure.h"
#endif
#include <cppunit/extensions/HelperMacros.h>
namespace LiveSupport {
namespace Scheduler {
using namespace LiveSupport;
using namespace LiveSupport::Core;
/* ================================================================ constants */
/* =================================================================== macros */
/* =============================================================== data types */
/**
* Unit test for the UploadPlaylistMetohd class.
*
* @author $Author: maroy $
* @version $Revision: 1.1 $
* @see UploadPlaylistMethod
*/
class UploadPlaylistMethodTest : public CPPUNIT_NS::TestFixture
{
CPPUNIT_TEST_SUITE(UploadPlaylistMethodTest);
CPPUNIT_TEST(firstTest);
CPPUNIT_TEST(overlappingPlaylists);
CPPUNIT_TEST_SUITE_END();
/**
* The name of the configuration file for the storage client factory.
*/
static const std::string storageClientConfig;
/**
* The name of the configuration file for the connection manager
* factory.
*/
static const std::string connectionManagerConfig;
/**
* The name of the configuration file for the schedule factory.
*/
static const std::string scheduleConfig;
/**
* The schedule used during the test.
*/
Ptr<ScheduleInterface>::Ref schedule;
/**
* Configure a configurable with an XML file.
*
* @param configurable configure this
* @param fileName the name of the XML file to configure with.
* @exception std::invalid_argument on configuration errors.
* @exception xmlpp::exception on XML parsing errors.
*/
void
configure(Ptr<Configurable>::Ref configurable,
std::string fileName)
throw (std::invalid_argument,
xmlpp::exception);
protected:
/**
* A simple test.
*
* @exception CPPUNIT_NS::Exception on test failures.
*/
void
firstTest(void) throw (CPPUNIT_NS::Exception);
/**
* Try to upload overlapping playlists, and see them fail.
*
* @exception CPPUNIT_NS::Exception on test failures.
*/
void
overlappingPlaylists(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 // UploadPlaylistMethodTest_h

View File

@ -0,0 +1,298 @@
/*------------------------------------------------------------------------------
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/XmlRpcDaemon.cxx,v $
------------------------------------------------------------------------------*/
/* ============================================================ include files */
#ifdef HAVE_CONFIG_H
#include "configure.h"
#endif
#if HAVE_SIGNAL_H
#include <signal.h>
#else
#error "Need signal.h"
#endif
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#else
#error "Need sys/stat.h"
#endif
#include <iostream>
#include <sstream>
#include <fstream>
#include <cstdio>
#include "SignalDispatcher.h"
#include "XmlRpcDaemonShutdownSignalHandler.h"
#include "XmlRpcDaemon.h"
using namespace LiveSupport::Scheduler;
/* =================================================== local data structures */
/* ================================================ local constants & macros */
/**
* The name of the XML configuration element for the Scheduler daemon.
*/
static const std::string confElement = "xmlRpcDaemon";
/**
* The name of the XML configuration attribute for the XML-RPC host name.
*/
static const std::string confXmlRpcHostAttr = "xmlRpcHost";
/**
* The name of the XML configuration attribute for the XML-RPC port.
*/
static const std::string confXmlRpcPortAttr = "xmlRpcPort";
/**
* The name of the XML configuration attribute for the process id file.
*/
static const std::string confPidFileNameAttr = "pidFileName";
/**
* The umask used by the daemon for file creations
*/
static const mode_t uMask = 027;
/* =============================================== local function prototypes */
/* ============================================================= module code */
/*------------------------------------------------------------------------------
* Configure the Scheder daemon according to an XML element
*----------------------------------------------------------------------------*/
void
XmlRpcDaemon :: configureXmlRpcDaemon(
const xmlpp::Element & element)
throw (std::invalid_argument,
std::logic_error)
{
if (configured) {
throw std::logic_error("already configured");
}
const xmlpp::Attribute * attribute;
std::stringstream strStr;
if (element.get_name() != confElement) {
std::string eMsg = "Bad configuration element ";
eMsg += element.get_name();
throw std::invalid_argument(eMsg);
}
if (!(attribute = element.get_attribute(confXmlRpcHostAttr))) {
std::string eMsg = "Missing attribute ";
eMsg += confXmlRpcHostAttr;
throw std::invalid_argument(eMsg);
}
xmlRpcHost = attribute->get_value();
if (!(attribute = element.get_attribute(confXmlRpcPortAttr))) {
std::string eMsg = "Missing attribute ";
eMsg += confXmlRpcPortAttr;
throw std::invalid_argument(eMsg);
}
strStr.str(attribute->get_value());
strStr >> xmlRpcPort;
if (!(attribute = element.get_attribute(confPidFileNameAttr))) {
std::string eMsg = "Missing attribute ";
eMsg += confPidFileNameAttr;
throw std::invalid_argument(eMsg);
}
pidFileName = attribute->get_value();
configured = true;
}
/*------------------------------------------------------------------------------
* Do all the necessary work of becoming a daemon.
* See http://www.enderunix.org/docs/eng/daemon.php and
* http://www.linuxprofilm.com/articles/linux-daemon-howto.html
* for hints.
*----------------------------------------------------------------------------*/
void
XmlRpcDaemon :: daemonize(void) throw (std::runtime_error)
{
int i;
if (getppid() == 1) {
// we're already a daemon
return;
}
i = fork();
if (i < 0) {
throw std::runtime_error("fork error");
} else if (i > 0) {
// this is the parent, simply return
return;
}
// now we're in the child process
// obtain a new process group
setsid();
// change the umask
umask(uMask);
// close standard file descriptors
/* TODO: don't close these until we don't have logging
std::cin.close();
std::cout.close();
std::cerr.close();
*/
// 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();
XmlRpcDaemonShutdownSignalHandler * handler =
new XmlRpcDaemonShutdownSignalHandler(this);
signalDispatcher->registerHandler(SIGHUP, handler);
signalDispatcher->registerHandler(SIGTERM, handler);
// FIXME: this signal handler will not be deleted by anyone,
// poddible memory leak
}
/*------------------------------------------------------------------------------
* Save the current process id.
*----------------------------------------------------------------------------*/
void
XmlRpcDaemon :: savePid(void) throw ()
{
std::ofstream pidFile(pidFileName.c_str());
pidFile << getpid();
pidFile.flush();
pidFile.close();
}
/*------------------------------------------------------------------------------
* Return the saved process id.
*----------------------------------------------------------------------------*/
pid_t
XmlRpcDaemon :: loadPid(void) throw ()
{
pid_t pid;
std::ifstream pidFile(pidFileName.c_str());
if (pidFile.fail()) {
return 0;
}
pidFile >> pid;
pidFile.close();
return pid;
}
/*------------------------------------------------------------------------------
* Start the daemon.
*----------------------------------------------------------------------------*/
void
XmlRpcDaemon :: start (void) throw (std::logic_error)
{
checkForConfiguration();
if (background) {
daemonize();
}
// and now our own XML-RPC methods
registerXmlRpcFunctions(xmlRpcServer);
// bind & run
XmlRpc::setVerbosity(5);
xmlRpcServer.bindAndListen(xmlRpcPort);
xmlRpcServer.work(-1.0);
}
/*------------------------------------------------------------------------------
* Tell if the daemon is running.
*----------------------------------------------------------------------------*/
bool
XmlRpcDaemon :: isRunning (void) throw (std::logic_error)
{
checkForConfiguration();
return loadPid();
}
/*------------------------------------------------------------------------------
* Stop the daemon.
*----------------------------------------------------------------------------*/
void
XmlRpcDaemon :: stop (void) throw (std::logic_error)
{
checkForConfiguration();
pid_t pid = loadPid();
kill(pid, SIGTERM);
}
/*------------------------------------------------------------------------------
* Shut down the daemon.
*----------------------------------------------------------------------------*/
void
XmlRpcDaemon :: shutdown (void) throw (std::logic_error)
{
checkForConfiguration();
xmlRpcServer.shutdown();
remove(pidFileName.c_str());
}

View File

@ -0,0 +1,397 @@
/*------------------------------------------------------------------------------
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/XmlRpcDaemon.h,v $
------------------------------------------------------------------------------*/
#ifndef XmlRpcDaemon_h
#define XmlRpcDaemon_h
#ifndef __cplusplus
#error This is a C++ include file
#endif
/* ============================================================ include files */
#ifdef HAVE_CONFIG_H
#include "configure.h"
#endif
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#else
#error "Need sys/types.h"
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#else
#error "Need unistd.h"
#endif
#include <string>
#include <stdexcept>
#include <libxml++/libxml++.h>
#include <XmlRpc.h>
namespace LiveSupport {
namespace Scheduler {
/* ================================================================ constants */
/* =================================================================== macros */
/* =============================================================== data types */
/**
* A generic XML-RPC daemon, that has to be sublclassed to provide
* real functionality.
*
* To use this class, subclass it, and override the configure() and
* registerXmlRpcFunctions() functions.
*
* The typical usage of the XmlRpcDaemon is as follows. To start the
* daemon:
* <ol>
* <li>create an instance of a subclass of XmlRpcDaemon</li>
* <li>call the configure() method with a proper XML element</li>
* <li>optionally call setBackground()</li>
* <li>call start() to start the daemon</li>
* </ol>
* Stopping the daemon is similar:
* <ol>
* <li>create an instance of a subclass of XmlRpcDaemon</li>
* <li>call the configure() method with a proper XML element
* if it has not yet been configured</li>
* <li>call stop() to stop the daemon</li>
* </ol>
*
* The structure of the XML configuration element used to configure the
* XML-RPC daemon is as follows:
*
* <pre><code>
* <xmlRpcDaemon xmlRpcHost = "hostname"
* xmlRpcPort = "portnumber"
* pidFileName = "pidfilename"
* background = "true"
* />
* </code></pre>
*
* The DTD for the above is:
* <pre><code>
* <!ELEMENT xmlRpcDaemon EMPTY >
* <!ATTLIST xmlRpcDaemon xmlRpcHost CDATA #REQUIRED >
* <!ATTLIST xmlRpcDaemon xmlRpcPort NMTOKEN #REQUIRED >
* <!ATTLIST xmlRpcDaemon pidFileName CDATA #REQUIRED >
* <!ATTLIST xmlRpcDaemon background (true|false) "true" >
* </code></pre>
*
*
* @author $Author: maroy $
* @version $Revision: 1.1 $
*/
class XmlRpcDaemon
{
private:
/**
* The host the XML-RPC server the daemon is
* listening on.
*/
std::string xmlRpcHost;
/**
* The port the XML-RPC server the daemon is
* listening on.
*/
unsigned int xmlRpcPort;
/**
* The name of the file where the daemon saves it's process id when
* running.
*/
std::string pidFileName;
/**
* Flag indicating if the singleton instnace has been
* configured already.
*/
bool configured;
/**
* Flag indicating wether to fork into background as a daemon
* or don't (good for debugging, for example).
* Defaults to true.
*/
bool background;
/**
* The XML-RPC server running within the Scheduler Daemon.
*/
XmlRpc::XmlRpcServer xmlRpcServer;
/**
* Do all the necessary tasks of becoming a daemon.
*
* @exception std::runtime_error on forking errors
*/
void
daemonize(void) throw (std::runtime_error);
/**
* Save the current process id to the process id file
*/
void
savePid(void) throw();
/**
* Return the saved process id.
*
* @return the saved process id of the daemon, or 0 if none saved.
*/
pid_t
loadPid(void) throw();
protected:
/**
* Default constructor.
*/
XmlRpcDaemon (void) throw ()
{
background = true;
configured = false;
}
/**
* Virtual destructor.
*/
virtual
~XmlRpcDaemon(void) throw ()
{
}
/**
* Check if the daemon has already been configured,
* and raise an exception if not so.
*
* @exception std::logic_error if the daemon has not yet been
* configured.
*/
void
checkForConfiguration(void) const throw (std::logic_error)
{
if (!configured) {
throw std::logic_error("not yet configured");
}
}
/**
* Configure the XML-RPC daemon itself. Pass an &lt;xmlRpcDaemon&gt;
* element to this function.
*
* @param element the XML element to configure the XML-RPC
* daemon from.
* @exception std::invalid_argument if the supplied XML element
* contains bad configuraiton information
* @exception std::logic_error if the daemon has already
* been configured.
*/
void
configureXmlRpcDaemon(const xmlpp::Element & element)
throw (std::invalid_argument,
std::logic_error);
/**
* Register your XML-RPC functions by implementing this function.
*/
virtual void
registerXmlRpcFunctions(XmlRpc::XmlRpcServer & xmlRpcServer)
throw (std::logic_error)
= 0;
public:
/**
* Tell if the daemon has already been configured.
* If so, an attempt to configure it again will result in an
* exception.
*
* @return true if the daemon has already been
* configured, false otherwise.
*/
const bool
isConfigured(void) const throw ()
{
return configured;
}
/**
* Set if the XML-RPC server should fork into background.
*
* @param background if true, the XML-RPC server will fork into
* background, otherwise not (good for debugging).
*/
void
setBackground(const bool background) throw ()
{
this->background = background;
}
/**
* Tell if the XML-RPC server will fork into background.
*
* @return if true, the XML-RPC server will fork into
* background, otherwise not (good for debugging).
*/
const bool
getBackground(void) const throw ()
{
return background;
}
/**
* Configure the daemon based on the XML element
* supplied.
* Implemtors should call the funtion configureXmlRpcDaemon
* from here with a proper &lt;xmlRpcDaemon&gt; element.
*
* @param element the XML element to configure the
* daemon from.
* @exception std::invalid_argument if the supplied XML element
* contains bad configuraiton information
* @exception std::logic_error if the daemon has already
* been configured.
* @see #configureXmlRpcDaemon
*/
virtual void
configure(const xmlpp::Element & element)
throw (std::invalid_argument,
std::logic_error)
= 0;
/**
* Tell the host name of the XML-RPC server the
* daemon is listening on.
*
* @return the host name of the XML-RPC server the
* daemon is listening on.
* @exception std::logic_error if the daemon has not
* yet been configured.
*/
const std::string
getXmlRpcHost(void) const throw (std::logic_error)
{
checkForConfiguration();
return xmlRpcHost;
}
/**
* Tell the port of the XML-RPC server the
* daemon is listening on.
*
* @return the port of the XML-RPC server the
* daemon is listening on.
* @exception std::logic_error if the daemon has not
* yet been configured.
*/
const unsigned int
getXmlRpcPort(void) const throw (std::logic_error)
{
checkForConfiguration();
return xmlRpcPort;
}
/**
* Tell the file name where the daemon stores its process id.
*
* @return the name of the file where the process id is stored.
* @exception std::logic_error if the daemon has not
* yet been configured.
*/
const std::string
getPidFileName(void) const throw (std::logic_error)
{
checkForConfiguration();
return pidFileName;
}
/**
* Start the daemon.
*
* @exception std::logic_error if the daemon has not
* yet been configured.
*/
void
start (void) throw (std::logic_error);
/**
* Tell if the deamon is running.
*
* @return true of the deamon is running, false otherwise.
* @exception std::logic_error if the daemon has not
* yet been configured.
*/
bool
isRunning (void) throw (std::logic_error);
/**
* Stop the daemon.
*
* @exception std::logic_error if the daemon has not
* yet been configured.
*/
void
stop (void) throw (std::logic_error);
/**
* Shut down the daemon.
* This function is public only because the signal handler
* needs visibility to this function, which will call it.
*
* @exception std::logic_error if the daemon has not
* yet been configured.
*/
void
shutdown (void) throw (std::logic_error);
};
/* ================================================= external data structures */
/* ====================================================== function prototypes */
} // namespace Scheduler
} // namespace LiveSupport
#endif // XmlRpcDaemon_h

View File

@ -0,0 +1,111 @@
/*------------------------------------------------------------------------------
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/XmlRpcDaemonShutdownSignalHandler.h,v $
------------------------------------------------------------------------------*/
#ifndef XmlRpcDaemonShutdownSignalHandler_h
#define XmlRpcDaemonShutdownSignalHandler_h
#ifndef __cplusplus
#error This is a C++ include file
#endif
/* ============================================================ include files */
#ifdef HAVE_CONFIG_H
#include "configure.h"
#endif
#include "SignalHandler.h"
#include "XmlRpcDaemon.h"
namespace LiveSupport {
namespace Scheduler {
/* ================================================================ constants */
/* =================================================================== macros */
/* =============================================================== data types */
/**
* Signal handler to shut down an XmlRpcDaemon.
*
* @author $Author: maroy $
* @version $Revision: 1.1 $
* @see XmlRpcDaemon
*/
class XmlRpcDaemonShutdownSignalHandler : public SignalHandler
{
private:
/**
* The XmlRpcDaemon to shut down.
*/
XmlRpcDaemon * xmlRpcDaemon;
public:
/**
* Constructor.
*
* @param xmlRpcDaemon the XmlRpcDaemon to shut down when the
* handler is invoked.
*/
XmlRpcDaemonShutdownSignalHandler(
XmlRpcDaemon * xmlRpcDaemon)
throw ()
{
this->xmlRpcDaemon = xmlRpcDaemon;
}
/**
* Handle the signal. Shuts down the XmlRpcDaemon used to
* construct this handler.
*
* @param signal the actual signal received.
*/
virtual void
handleSignal(int signal) throw ()
{
xmlRpcDaemon->shutdown();
}
};
/* ================================================= external data structures */
/* ====================================================== function prototypes */
} // namespace Scheduler
} // namespace LiveSupport
#endif // XmlRpcDaemonShutdownSignalHandler_h

View File

@ -0,0 +1,243 @@
/*------------------------------------------------------------------------------
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/main.cxx,v $
------------------------------------------------------------------------------*/
/** @file
* This file contains the main entry point to the Scheduler daemon.
*/
/* ============================================================ include files */
#ifdef HAVE_CONFIG_H
#include "configure.h"
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#else
#error "Need unistd.h"
#endif
#if HAVE_GETOPT_H
#include <getopt.h>
#else
#error "Need getopt.h"
#endif
#include <memory>
#include <string>
#include <iostream>
#include <stdexcept>
#include "SchedulerDaemon.h"
using namespace LiveSupport::Scheduler;
/* =================================================== local data structures */
/* ================================================ local constants & macros */
/**
* Our copyright notice, should be at most 80 columns
*/
static const char copyrightNotice[] =
"Copyright (c) 2004 Media Development Loan Fund under the GNU GPL";
/**
* String describing the short options.
*/
static const char options[] = "c:dhv";
/**
* Structure describing the long options
*/
static const struct option longOptions[] = {
{ "config", required_argument, 0, 'c' },
{ "debug", no_argument, 0, 'd' },
{ "help", no_argument, 0, 'h' },
{ "version", no_argument, 0, 'v' },
{ 0, 0, 0, 0 }
};
/**
* The start command: "start"
*/
static const std::string startCommand = "start";
/**
* The status command: "status"
*/
static const std::string statusCommand = "status";
/**
* The stop command: "stop"
*/
static const std::string stopCommand = "stop";
/* =============================================== local function prototypes */
/**
* Print program version.
*
* @param os the std::ostream to print to.
*/
static void
printVersion ( std::ostream & os );
/**
* Print program usage information.
*
* @param invocation the command line command used to invoke this program.
* @param os the std::ostream to print to.
*/
static void
printUsage ( const char invocation[],
std::ostream & os );
/* ============================================================= module code */
/**
* Program entry point.
*
* @param argc the number of command line arguments passed by the user.
* @param argv the command line arguments passed by the user.
* @return 0 on success, non-0 on failure.
*/
int main ( int argc,
char * argv[] )
{
int i;
std::string configFileName;
bool debugMode = false;
while ((i = getopt_long(argc, argv, options, longOptions, 0)) != -1) {
switch (i) {
case 'c':
configFileName = optarg;
break;
case 'd':
debugMode = true;
break;
case 'h':
printUsage(argv[0], std::cout);
return 0;
case 'v':
printVersion(std::cout);
return 0;
default:
printUsage(argv[0], std::cout);
return 1;
}
}
if (optind != argc - 1) {
printUsage(argv[0], std::cout);
return 1;
}
std::cerr << "using config file '" << configFileName << '\'' << std::endl;
SchedulerDaemon * daemon = SchedulerDaemon::getInstance();
try {
std::auto_ptr<xmlpp::DomParser>
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 << "semantic error in configuration file" << std::endl
<< e.what() << std::endl;
return 1;
} catch (xmlpp::exception &e) {
std::cerr << "error parsing configuration file" << std::endl
<< e.what() << std::endl;
return 1;
}
daemon->setBackground(!debugMode);
if (startCommand == argv[optind]) {
daemon->start();
} else if (statusCommand == argv[optind]) {
std::cout << "The Scheduler Daemon is "
<< (daemon->isRunning() ? "" : "not ")
<< "running" << std::endl;
} else if (stopCommand == argv[optind]) {
daemon->stop();
} else {
printUsage(argv[0], std::cout);
return 1;
}
return 0;
}
/*------------------------------------------------------------------------------
* Print program version.
*----------------------------------------------------------------------------*/
static void
printVersion ( std::ostream & os )
{
os << PACKAGE_NAME << ' ' << PACKAGE_VERSION << std::endl
<< copyrightNotice << std::endl;
}
/*------------------------------------------------------------------------------
* Print program usage.
*----------------------------------------------------------------------------*/
static void
printUsage ( const char invocation[],
std::ostream & os )
{
os << PACKAGE_NAME << ' ' << PACKAGE_VERSION << std::endl
<< std::endl
<< "Usage: " << invocation << " [OPTION] COMMAND"
<< std::endl
<< " COMMAND is one of: start, stop or status" << std::endl
<< std::endl
<< " mandatory options:" << std::endl
<< " -c, --config=file.name scheduler configuration file" << std::endl
<< " optional options:" << std::endl
<< " -d, --debug don't fork into background" << std::endl
<< " -h, --help display this help and exit" << std::endl
<< " -v, --version display version information and exit"
<< std::endl
<< std::endl
<< "Report bugs to " << PACKAGE_BUGREPORT << std::endl;
}

View File

@ -0,0 +1 @@
keep me