SchedulerDaemon.cxx

Go to the documentation of this file.
00001 /*------------------------------------------------------------------------------
00002  
00003     Copyright (c) 2004 Media Development Loan Fund
00004  
00005     This file is part of the Campcaster project.
00006     https://www.campware.org/
00007     To report bugs, send an e-mail to [email protected]
00008  
00009     Campcaster is free software; you can redistribute it and/or modify
00010     it under the terms of the GNU General Public License as published by
00011     the Free Software Foundation; either version 2 of the License, or
00012     (at your option) any later version.
00013  
00014     Campcaster is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017     GNU General Public License for more details.
00018  
00019     You should have received a copy of the GNU General Public License
00020     along with Campcaster; if not, write to the Free Software
00021     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022  
00023  
00024     Author   : $Author: paul $
00025     Version  : $Revision: 2833 $
00026     Location : $URL: svn://code.campware.org/campcaster/trunk/campcaster/src/products/scheduler/src/SchedulerDaemon.cxx $
00027  
00028 ------------------------------------------------------------------------------*/
00029 
00030 /* ============================================================ include files */
00031 
00032 #ifdef HAVE_CONFIG_H
00033  #include "configure.h"
00034 #endif
00035  
00036 #if HAVE_SIGNAL_H
00037  #include <signal.h>
00038 #else
00039  #error "Need signal.h"
00040  #endif
00041  
00042 #if HAVE_SYS_STAT_H
00043  #include <sys/stat.h>
00044 #else
00045  #error "Need sys/stat.h"
00046  #endif
00047  
00048 
00049 #include <iostream>
00050 #include <sstream>
00051 #include <fstream>
00052 #include <cstdio>
00053 
00054 #include <boost/date_time/posix_time/posix_time.hpp>
00055 
00056 #include "LiveSupport/Db/ConnectionManagerFactory.h"
00057 #include "LiveSupport/Authentication/AuthenticationClientFactory.h"
00058 #include "LiveSupport/StorageClient/StorageClientFactory.h"
00059 #include "LiveSupport/PlaylistExecutor/AudioPlayerFactory.h"
00060 #include "ScheduleFactory.h"
00061 #include "PlayLogFactory.h"
00062 #include "BackupFactory.h"
00063 #include "PlaylistEventContainer.h"
00064 
00065 #include "SchedulerDaemon.h"
00066 
00067 using namespace boost::posix_time;
00068 
00069 using namespace LiveSupport;
00070 using namespace LiveSupport::Core;
00071 using namespace LiveSupport::Db;
00072 using namespace LiveSupport::StorageClient;
00073 using namespace LiveSupport::Scheduler;
00074 
00075 /* ===================================================  local data structures */
00076 
00077 
00078 /* ================================================  local constants & macros */
00079 
00083 Ptr<SchedulerDaemon>::Ref   SchedulerDaemon::schedulerDaemon;
00084 
00085 namespace {
00086 
00090 const std::string confElement = "scheduler";
00091 
00095 const std::string xmlRpcDaemonConfElement = "xmlRpcDaemon";
00096 
00100 const std::string    userConfigElementName = "user";
00101 
00105 const std::string    userLoginAttrName = "login";
00106 
00110 const std::string    userPasswordAttrName = "password";
00111 
00112 }
00113 
00114 /* ===============================================  local function prototypes */
00115 
00116 
00117 /* =============================================================  module code */
00118 
00119 /*------------------------------------------------------------------------------
00120  *  The default constructor.
00121  *----------------------------------------------------------------------------*/
00122 SchedulerDaemon :: SchedulerDaemon (void)                   throw ()
00123                         : XmlRpcDaemon()
00124 {
00125     displayScheduleMethod.reset(new DisplayScheduleMethod());
00126     generatePlayReportMethod.reset(new GeneratePlayReportMethod());
00127     getSchedulerTimeMethod.reset(new GetSchedulerTimeMethod());
00128     getVersionMethod.reset(new GetVersionMethod());
00129     removeFromScheduleMethod.reset(new RemoveFromScheduleMethod());
00130     rescheduleMethod.reset(new RescheduleMethod());
00131     uploadPlaylistMethod.reset(new UploadPlaylistMethod());
00132     loginMethod.reset(new LoginMethod());
00133     logoutMethod.reset(new LogoutMethod());
00134     resetStorageMethod.reset(new ResetStorageMethod());
00135     createBackupOpenMethod.reset(new CreateBackupOpenMethod());
00136     createBackupCheckMethod.reset(new CreateBackupCheckMethod());
00137     createBackupCloseMethod.reset(new CreateBackupCloseMethod());
00138     restoreBackupMethod.reset(new RestoreBackupMethod());
00139     stopCurrentlyPlayingMethod.reset(new StopCurrentlyPlayingMethod());
00140 }
00141 
00142 
00143 /*------------------------------------------------------------------------------
00144  *  Return the singleton instnace.
00145  *----------------------------------------------------------------------------*/
00146 Ptr<SchedulerDaemon>::Ref
00147 SchedulerDaemon :: getInstance (void)                       throw ()
00148 {
00149     if (!schedulerDaemon) {
00150         schedulerDaemon.reset(new SchedulerDaemon());
00151     }
00152 
00153     return schedulerDaemon;
00154 }
00155 
00156 
00157 /*------------------------------------------------------------------------------
00158  *  Configure the scheduler daemon
00159  *----------------------------------------------------------------------------*/
00160 void
00161 SchedulerDaemon :: configure(const xmlpp::Element    & element)
00162                                                 throw (std::invalid_argument,
00163                                                        std::logic_error)
00164 {
00165     if (element.get_name() != confElement) {
00166         std::string eMsg = "Bad configuration element ";
00167         eMsg += element.get_name();
00168         throw std::invalid_argument(eMsg);
00169     }
00170 
00171     xmlpp::Node::NodeList       nodes;
00172     const xmlpp::Element      * elem = 0;
00173     const xmlpp::Attribute    * attribute = 0;
00174 
00175     // read in the user data
00176 
00177     nodes = element.get_children(userConfigElementName);
00178     if (nodes.size() < 1) {
00179         throw std::invalid_argument("no user element");
00180     }
00181     elem = dynamic_cast<const xmlpp::Element*> (*nodes.begin());
00182     if (!(attribute = elem->get_attribute(userLoginAttrName))) {
00183         throw std::invalid_argument("missing login attribute");
00184     }
00185     login = attribute->get_value();
00186     if (!(attribute = elem->get_attribute(userPasswordAttrName))) {
00187         throw std::invalid_argument("missing password attribute");
00188     }
00189     password = attribute->get_value();
00190 
00191     // configure the ConnectionManagerFactory
00192     nodes =
00193          element.get_children(ConnectionManagerFactory::getConfigElementName());
00194     if (nodes.size() < 1) {
00195         throw std::invalid_argument("no connectionManagerFactory  element");
00196     }
00197     Ptr<ConnectionManagerFactory>::Ref cmf
00198                                 = ConnectionManagerFactory::getInstance();
00199     cmf->configure( *((const xmlpp::Element*) *(nodes.begin())) );
00200 
00201     // configure the AuthenticationClientFactory
00202     nodes =
00203       element.get_children(AuthenticationClientFactory::getConfigElementName());
00204     if (nodes.size() < 1) {
00205         throw std::invalid_argument("no authenticationClientFactory element");
00206     }
00207     Ptr<AuthenticationClientFactory>::Ref acf
00208                                 = AuthenticationClientFactory::getInstance();
00209     acf->configure( *((const xmlpp::Element*) *(nodes.begin())) );
00210 
00211     // configure the StorageClientFactory
00212     nodes = element.get_children(StorageClientFactory::getConfigElementName());
00213     if (nodes.size() < 1) {
00214         throw std::invalid_argument("no storageClientFactory element");
00215     }
00216     Ptr<StorageClientFactory>::Ref scf = StorageClientFactory::getInstance();
00217     scf->configure( *((const xmlpp::Element*) *(nodes.begin())) );
00218 
00219     // configure the AudioPlayerFactory
00220     nodes = element.get_children(AudioPlayerFactory::getConfigElementName());
00221     if (nodes.size() < 1) {
00222         throw std::invalid_argument("no audioPlayer element");
00223     }
00224     Ptr<AudioPlayerFactory>::Ref    apf = AudioPlayerFactory::getInstance();
00225     apf->configure( *((const xmlpp::Element*) *(nodes.begin())) );
00226 
00227     // configure the ScheduleFactory
00228     nodes = element.get_children(ScheduleFactory::getConfigElementName());
00229     if (nodes.size() < 1) {
00230         throw std::invalid_argument("no scheduleFactory element");
00231     }
00232     Ptr<ScheduleFactory>::Ref   sf = ScheduleFactory::getInstance();
00233     sf->configure( *((const xmlpp::Element*) *(nodes.begin())) );
00234 
00235     // configure the PlayLogFactory
00236     nodes = element.get_children(PlayLogFactory::getConfigElementName());
00237     if (nodes.size() < 1) {
00238         throw std::invalid_argument("no playLogFactory element");
00239     }
00240     Ptr<PlayLogFactory>::Ref   plf = PlayLogFactory::getInstance();
00241     plf->configure( *((const xmlpp::Element*) *(nodes.begin())) );
00242 
00243     // configure the BackupFactory
00244     nodes = element.get_children(BackupFactory::getConfigElementName());
00245     if (nodes.size() < 1) {
00246         throw std::invalid_argument("no backupFactory element");
00247     }
00248     Ptr<BackupFactory>::Ref     bf = BackupFactory::getInstance();
00249     bf->configure( *((const xmlpp::Element*) *(nodes.begin())) );
00250 
00251     // configure the XmlRpcDaemon
00252     nodes = element.get_children(XmlRpcDaemon::getConfigElementName());
00253     if (nodes.size() < 1) {
00254         throw std::invalid_argument("no xmlRpcDaemon element");
00255     }
00256     configureXmlRpcDaemon( *((const xmlpp::Element*) *(nodes.begin())) );
00257 
00258     // do some initialization, using the configured objects
00259     authentication    = acf->getAuthenticationClient();
00260     connectionManager = cmf->getConnectionManager();
00261     storage           = scf->getStorageClient();
00262     audioPlayer       = apf->getAudioPlayer();
00263     schedule          = sf->getSchedule();
00264     playLog           = plf->getPlayLog();
00265 }
00266 
00267 
00268 /*------------------------------------------------------------------------------
00269  *  Destructor.
00270  *----------------------------------------------------------------------------*/
00271 SchedulerDaemon :: ~SchedulerDaemon(void)                       throw ()
00272 {
00273     if (authentication.get() && sessionId.get()) {
00274         authentication->logout(sessionId);
00275     }
00276 }
00277 
00278 
00279 /*------------------------------------------------------------------------------
00280  *  Register our XML-RPC methods
00281  *----------------------------------------------------------------------------*/
00282 void
00283 SchedulerDaemon :: registerXmlRpcFunctions(
00284                             Ptr<XmlRpc::XmlRpcServer>::Ref  xmlRpcServer)
00285                                                     throw (std::logic_error)
00286 {
00287     xmlRpcServer->addMethod(displayScheduleMethod.get());
00288     xmlRpcServer->addMethod(generatePlayReportMethod.get());
00289     xmlRpcServer->addMethod(getSchedulerTimeMethod.get());
00290     xmlRpcServer->addMethod(getVersionMethod.get());
00291     xmlRpcServer->addMethod(removeFromScheduleMethod.get());
00292     xmlRpcServer->addMethod(rescheduleMethod.get());
00293     xmlRpcServer->addMethod(uploadPlaylistMethod.get());
00294     xmlRpcServer->addMethod(loginMethod.get());
00295     xmlRpcServer->addMethod(logoutMethod.get());
00296     xmlRpcServer->addMethod(resetStorageMethod.get());
00297     xmlRpcServer->addMethod(createBackupOpenMethod.get());
00298     xmlRpcServer->addMethod(createBackupCheckMethod.get());
00299     xmlRpcServer->addMethod(createBackupCloseMethod.get());
00300     xmlRpcServer->addMethod(restoreBackupMethod.get());
00301     xmlRpcServer->addMethod(stopCurrentlyPlayingMethod.get());
00302 }
00303 
00304 
00305 /*------------------------------------------------------------------------------
00306  *  Execute daemon startup functions.
00307  *----------------------------------------------------------------------------*/
00308 void
00309 SchedulerDaemon :: startup (void)                   throw (std::logic_error)
00310 {
00311     try {
00312         sessionId      = authentication->login(login, password);
00313     } catch (XmlRpcException &e) {
00314         throw std::logic_error(std::string("authentication problem: ")
00315                                + e.what());
00316     }
00317 
00318     try {
00319         audioPlayer->initialize();
00320     } catch (std::exception &e) {
00321         throw std::logic_error(std::string("audio player initialization "
00322                                "problem: ") + e.what());
00323     }
00324     if (!eventScheduler.get()) {
00325         Ptr<PlaylistEventContainer>::Ref    eventContainer;
00326         Ptr<time_duration>::Ref             granularity;
00327         eventContainer.reset(new PlaylistEventContainer(sessionId,
00328                                                         storage,
00329                                                         schedule,
00330                                                         audioPlayer,
00331                                                         playLog));
00332         // TODO: read granularity from config file
00333         granularity.reset(new time_duration(seconds(1)));
00334 
00335         eventScheduler.reset(
00336                 new LiveSupport::EventScheduler::EventScheduler(eventContainer,
00337                                                                 granularity));
00338     }
00339     eventScheduler->start();
00340 
00341     XmlRpcDaemon::startup();
00342 }
00343 
00344 
00345 /*------------------------------------------------------------------------------
00346  *  Shut down the daemon
00347  *----------------------------------------------------------------------------*/
00348 void
00349 SchedulerDaemon :: shutdown(void)               throw (std::logic_error)
00350 {
00351     if (eventScheduler.get()) {
00352         eventScheduler->stop();
00353     }
00354     audioPlayer->deInitialize();
00355 
00356     XmlRpcDaemon::shutdown();
00357 }
00358 
00359 
00360 /*------------------------------------------------------------------------------
00361  *  Re-read the events from the event container.
00362  *----------------------------------------------------------------------------*/
00363 void
00364 SchedulerDaemon :: update (void)                throw (std::logic_error)
00365 {
00366     // TODO: check if we've been configured
00367     if (eventScheduler.get()) {
00368         eventScheduler->update();
00369     }
00370 }
00371 

Generated on Thu Sep 20 02:00:30 2007 for Campcaster by  1.4.7