• Classes
  • Modules
  • Namespaces
  • Files
  • Related Pages
  • File List
  • File Members

acsRequest.h

Go to the documentation of this file.
00001 #ifndef _ACS_REQUEST_H_
00002 #define _ACS_REQUEST_H_
00003 
00004 /*******************************************************************************
00005 *    ALMA - Atacama Large Millimiter Array
00006 *    (c) European Southern Observatory, 2002
00007 *    Copyright by ESO (in the framework of the ALMA collaboration)
00008 *    and Cosylab 2002, All rights reserved
00009 *
00010 *    This library is free software; you can redistribute it and/or
00011 *    modify it under the terms of the GNU Lesser General Public
00012 *    License as published by the Free Software Foundation; either
00013 *    version 2.1 of the License, or (at your option) any later version.
00014 *
00015 *    This library is distributed in the hope that it will be useful,
00016 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 *    Lesser General Public License for more details.
00019 *
00020 *    You should have received a copy of the GNU Lesser General Public
00021 *    License along with this library; if not, write to the Free Software
00022 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
00023 *
00024 * "@(#) $Id: acsRequest.h,v 1.7 2009/09/29 15:30:59 msekoran Exp $"
00025 *
00026 * who       when      what
00027 * --------  --------  ----------------------------------------------
00028 * azagar   2008-08-12 created
00029 */
00030 
00031 #include "acsdaemonS.h"
00032 #include <acsThread.h>
00033 #include <acsutilPorts.h>
00034 #include <queue>
00035 #include <memory>
00036 
00037 // callback call timeout
00038 #define CORBA_TIMEOUT 5000
00039 
00040 /*** exit codes of startup/shutdown scripts ***/
00041 // all fine
00042 #define EC_OK 0
00043 // can't create requested acs instance: already exists
00044 #define EC_CANNOTCREATE 40
00045 // can't use requested acs instance: doesn't exist or is owned by somebody else
00046 #define EC_CANNOTUSE 41
00047 // general failure, no details known
00048 #define EC_FAILURE 42
00049 // command line arguments wrong or missing
00050 #define EC_BADARGS 43
00051 // can't run requested servant: no port available
00052 #define EC_NOPORT 44
00053 // can't run requested servant: launch attempt timed out
00054 #define EC_TIMEOUT 45
00055 
00056 struct ACSService {
00057     const char *xmltag;
00058     const char *script;
00059     const char *impname;   // Name of services handler (used for logging purposes)
00060     const char *imptype;   // CORBA-type for this services handler
00061     const char *impport;
00062     const char *impexec;
00063     const char *svccorbaurl;
00064     std::string (*svcport)(int);
00065     std::string (*namedsvcport)(int, const char *);
00066     bool autorestart;      // Should ACS service automatically restart
00067 };
00068 
00069 enum ACSServiceType {
00070     NAMING_SERVICE = 0,
00071     NOTIFICATION_SERVICE,
00072     CDB,
00073     MANAGER,
00074     ACS_LOG_SERVICE,
00075     LOGGING_SERVICE,
00076     INTERFACE_REPOSITORY,
00077     ALARM_SERVICE,
00078     UNKNOWN
00079 };
00080 
00081 #define ACS_SERVICE_TYPES UNKNOWN
00082 #define ACS_SERVICE_INSTANCES 10
00083 
00084 const ACSService acsServices[] = {
00085     {
00086       "naming_service",
00087       "acsNamingService",
00088       "Naming Service Imp",
00089       "NamingServiceImp",
00090       "2981",
00091       "acsutilBlock -t 15 -s -k -b \"Imp is up and running...\" acsdaemonNamingServiceImp",
00092       "corbaloc::%s:%s/NameService",
00093       &ACSPorts::getNamingServicePort,
00094       NULL,
00095       false
00096     }, {
00097       "notification_service",
00098       "acsNotifyService",
00099       "Notification Service Imp",
00100       "NotificationServiceImp",
00101       "2982",
00102       "acsutilBlock -t 15 -s -k -b \"Imp is up and running...\" acsdaemonNotificationServiceImp",
00103       "corbaloc::%s:%s/%s",
00104       NULL,
00105       &ACSPorts::getNotifyServicePort,
00106       true
00107     }, {
00108       "cdb",
00109       "acsConfigurationDatabase",
00110       "CDB Imp",
00111       "ConfigurationDatabaseImp",
00112       "2983",
00113       "acsutilBlock -t 15 -s -k -b \"Imp is up and running...\" acsdaemonConfigurationDatabaseImp",
00114       "corbaloc::%s:%s/CDB",
00115       &ACSPorts::getCDBPort,
00116       NULL,
00117       false
00118     }, {
00119       "manager",
00120       "acsManager",
00121       "Manager Imp",
00122       "ManagerImp",
00123       "2984",
00124       "acsutilBlock -t 15 -s -k -b \"Imp is up and running...\" acsdaemonManagerImp",
00125       "corbaloc::%s:%s/Manager",
00126       &ACSPorts::getManagerPort,
00127       NULL,
00128       false
00129     }, {
00130       "acs_log",
00131       "acsACSLogService",
00132       "ACS Log Service Imp",
00133       "ACSLogServiceImp",
00134       "2985",
00135       "acsutilBlock -t 15 -s -k -b \"Imp is up and running...\" acsdaemonACSLogServiceImp",
00136       "corbaloc::%s:%s/ACSLogSvc",
00137       &ACSPorts::getLogPort,
00138       NULL,
00139       false
00140     }, {
00141       "logging_service",
00142       "acsLoggingService",
00143       "Logging Service Imp",
00144       "LoggingServiceImp",
00145       "2986",
00146       "acsutilBlock -t 15 -s -k -b \"Imp is up and running...\" acsdaemonLoggingServiceImp",
00147       "corbaloc::%s:%s/Log",
00148       &ACSPorts::getLoggingServicePort,
00149       NULL,
00150       true
00151     }, {
00152       "interface_repository",
00153       "acsInterfaceRepository",
00154       "Interface Repository Imp",
00155       "InterfaceRepositoryImp",
00156       "2987",
00157       "acsutilBlock -t 15 -s -k -b \"Imp is up and running...\" acsdaemonInterfaceRepositoryImp",
00158       "corbaloc::%s:%s/InterfaceRepository",
00159       &ACSPorts::getIRPort,
00160       NULL,
00161       false
00162     }, {
00163       "alarm_service",
00164       "acsAlarmService",
00165       "Alarm Service Imp",
00166       "AlarmServiceImp",
00167       "2988",
00168       "acsutilBlock -t 15 -s -k -b \"Imp is up and running...\" acsdaemonAlarmServiceImp",
00169       "corbaloc::%s:%s/AcsAlarmService",
00170       &ACSPorts::getAlarmServicePort,
00171       NULL,
00172       false
00173     }, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, false }
00174 };
00175 
00176 enum ACSServiceRequestType {
00177     START_SERVICE,
00178     STOP_SERVICE
00179 };
00180 
00181 enum ACSServiceRequestTarget {
00182     LOCAL,
00183     DAEMON,
00184     IMP
00185 };
00186 
00187 ACSServiceType acsServiceXMLTagToEnum(const char *service);
00188 
00189 class RequestProcessorThread;
00190 
00191 class Request {
00192   public:
00193     virtual ~Request() {};
00194     virtual void abort() = 0;
00195     virtual bool execute() = 0;
00196 };
00197 
00198 class RequestProcessorThread : public ACS::Thread {
00199   private:
00200     ACE_Thread_Mutex *m_mutex;
00201     ACE_Condition<ACE_Thread_Mutex> *m_wait;
00202     std::queue<Request*> pending;
00203     volatile bool running;
00204   public:
00205     RequestProcessorThread(const ACE_CString &name,
00206            const ACS::TimeInterval& responseTime=ThreadBase::defaultResponseTime, 
00207            const ACS::TimeInterval& sleepTime=ThreadBase::defaultSleepTime);
00208     ~RequestProcessorThread();
00209     void onStart();
00210     void stop();
00211     void exit();
00212     void runLoop() ACE_THROW_SPEC ((CORBA::SystemException, ::ACSErrTypeCommon::BadParameterEx));
00213     void process(Request* r);
00214 };
00215 
00216 template <class R> class RequestChainContext;
00217 
00218 template <class R> class ChainedRequest : public Request {
00219   private:
00220     RequestChainContext<R> *context;
00221     friend class RequestChainContext<R>;
00222     void process(RequestChainContext<R> *icontext);
00223   protected:
00224     virtual void complete();
00225   public:
00226     ChainedRequest() : context(NULL) {}
00227 };
00228 
00229 template <class R> class RequestChainContext {
00230   private:
00231     RequestProcessorThread *rpt;
00232     std::deque<R*> requests;
00233     R *curreq;
00234     bool inprocess;
00235   protected:
00236     virtual bool requestDone(R *request) = 0;
00237     virtual void chainDone() = 0;
00238     virtual void chainAborted() = 0;
00239   public:
00240     RequestChainContext(RequestProcessorThread *irpt) : rpt(irpt), curreq(NULL), inprocess(false) {}
00241     virtual ~RequestChainContext() {
00242         while (!requests.empty()) {
00243             delete requests.front();
00244             requests.pop_front();
00245         }
00246     }
00247     RequestProcessorThread *getRequestProcessor() { return rpt; }
00248     void appendRequest(R *request) { requests.push_back(request); }
00249     void prependRequest(R *request) { requests.push_front(request); }
00250     void proceed(R *lastreq = NULL);
00251 };
00252 
00253 /*********************** ACS SERVICES SPECIFIC REQUESTS ***********************/
00254 
00255 class ACSServiceRequestChainContext;
00256 
00257 class ACSServiceRequestDescription {
00258   private:
00259     ACSServiceType service;
00260     int instance_number;
00261     const char *host, *name, *corbalocName, *domain, *cdbxmldir;
00262     bool loadir, wait, recovery;
00263     ACE_CString prepareCommand(ACSServiceRequestType request_type, bool log);
00264   public:
00265     ACSServiceRequestDescription(ACSServiceType iservice, int iinstance_number);
00266     ACSServiceRequestDescription(const ACSServiceRequestDescription &desc);
00267     ~ACSServiceRequestDescription();
00268     ACSErr::Completion_var executeLocal(ACSServiceRequestType request_type);
00269     ACSErr::Completion_var executeRemote(ACSServiceRequestType request_type, CORBA::ORB_ptr orb, acsdaemon::DaemonCallback_ptr cbptr, const char *corbaloc);
00270     void setFromXMLAttributes(const char **atts);
00271     void setName(const char *iname) { name = iname == NULL ? NULL : strdup(iname); }
00272     void setCorbalocName(const char *iname) { corbalocName = iname == NULL ? NULL : strdup(iname); }
00273     void setDomain(const char *idomain) { domain = idomain == NULL ? NULL : strdup(idomain); }
00274     void setLoadIR(bool iloadir) { loadir = iloadir; }
00275     void setWaitLoadIR(bool iwait) { wait = iwait; }
00276     void setRecovery(bool irecovery) { recovery = irecovery; }
00277     void setCdbXMLDir(const char *icdbxmldir) { cdbxmldir = icdbxmldir == NULL ? NULL : strdup(icdbxmldir); }
00278     int getInstanceNumber() { return instance_number; }
00279     const char *getName() { return name; }
00280     const char *getCorbalocName() { return corbalocName; } 
00281     const char *getHost() { return host == NULL ? ACSPorts::getIP() : host; }
00282     ACSServiceType getACSService() { return service; }
00283     const char *getACSServiceName() { return acsServices[service].xmltag; }
00284 };
00285 
00286 class ACSDaemonContext;
00287 
00288 class ACSServiceRequest : public ChainedRequest<ACSServiceRequest>, POA_acsdaemon::DaemonCallback {
00289   private:
00290     ACSDaemonContext *context;
00291     ACSServiceRequestTarget target;
00292     ACSServiceRequestType request_type;
00293     ACSServiceRequestDescription *desc;
00294     acsdaemon::DaemonCallback_var callback;
00295     const ACSErr::Completion *completion;
00296     acsdaemon::DaemonCallback_var cbvar;
00297     acsdaemon::DaemonCallback_ptr cbptr();
00298     void release();
00299   protected:
00300     void complete();
00301     void abort();
00302     bool execute();
00303   public:
00304     ACSServiceRequest(ACSDaemonContext *icontext, ACSServiceRequestTarget itarget, ACSServiceRequestType itype, ACSServiceRequestDescription *idesc, acsdaemon::DaemonCallback_ptr icallback = NULL);
00305     ~ACSServiceRequest();
00306     void done(const ::ACSErr::Completion &comp);
00307     void working(const ::ACSErr::Completion &comp);
00308     const ACSErr::Completion *getCompletion() { return completion; }
00309     bool isErrorFree() { return completion == NULL || completion->previousError.length() == 0; }
00310     ACSServiceRequestTarget getRequestTarget() { return target; }
00311     ACSServiceRequestDescription *getDescription() { return desc; }
00312     const char *getACSServiceName() { return desc->getACSServiceName(); }
00313     int getInstanceNumber() { return desc->getInstanceNumber(); }
00314     const char *getHost() { return desc->getHost(); }
00315 };
00316 
00317 class ACSServiceRequestChainContext : public RequestChainContext<ACSServiceRequest> {
00318   private:
00319     ACSDaemonContext *context;
00320     ACSServiceRequestType request_type;
00321     bool reuse_services;
00322     acsdaemon::DaemonSequenceCallback_var callback;
00323     int instance_number;
00324   protected:
00325     bool requestDone(ACSServiceRequest *request);
00326     void chainDone();
00327     void chainAborted();
00328   public:
00329     ACSServiceRequestChainContext(ACSDaemonContext *icontext, ACSServiceRequestType itype, bool ireuse_services, acsdaemon::DaemonSequenceCallback_ptr icallback);
00330     ~ACSServiceRequestChainContext();
00331     void addRequest(const char *iservice, const char **atts);
00332     void startProcessing() { proceed(); }
00333 };
00334 
00335 
00336 #endif

Generated on Thu Jan 12 2012 23:13:50 for ACS-10.0 C++ API by  doxygen 1.7.0