00001 #ifndef _ACS_REQUEST_H_
00002 #define _ACS_REQUEST_H_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "acsdaemonS.h"
00032 #include <acsThread.h>
00033 #include <acsutilPorts.h>
00034 #include <queue>
00035 #include <memory>
00036
00037
00038 #define CORBA_TIMEOUT 5000
00039
00040
00041
00042 #define EC_OK 0
00043
00044 #define EC_CANNOTCREATE 40
00045
00046 #define EC_CANNOTUSE 41
00047
00048 #define EC_FAILURE 42
00049
00050 #define EC_BADARGS 43
00051
00052 #define EC_NOPORT 44
00053
00054 #define EC_TIMEOUT 45
00055
00056 struct ACSService {
00057 const char *xmltag;
00058 const char *script;
00059 const char *impname;
00060 const char *imptype;
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;
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
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