00001 #ifndef _ACS_DAEMON_IMPL_H_
00002 #define _ACS_DAEMON_IMPL_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
00032
00033 #ifndef __cplusplus
00034 #error This is a C++ include file and cannot be used from plain C
00035 #endif
00036
00037 #include "acsdaemonS.h"
00038 #include <ace/SString.h>
00039 #include "logging.h"
00040 #include <getopt.h>
00041 #include <acsutilPorts.h>
00042 #include <tao/IORTable/IORTable.h>
00043 #include <acserr.h>
00044 #include <acsdaemonErrType.h>
00045 #include <ACSErrTypeCommon.h>
00046 #include "acsdaemonORBTask.h"
00047
00054 template <typename T>
00055 class ACSDaemonServiceImpl {
00056
00057 public:
00058
00062 ACSDaemonServiceImpl(LoggingProxy &logProxy, bool isProtected);
00063
00067 virtual ~ACSDaemonServiceImpl();
00068
00072 bool
00073 isInitialized() { return m_isInitialized; }
00074
00078 bool
00079 isProtected() { return m_isProtected; }
00080
00081
00085 std::string
00086 getPort() { return handler.getPort(); }
00087
00091 std::string
00092 getName() { return handler.getName(); }
00093
00097 int
00098 startup (int argc, char *argv[]);
00099
00104 int
00105 run ();
00106
00110 void
00111 shutdown (bool wait_for_completition);
00112
00116 const char*
00117 getIOR() const { return m_ior.in(); };
00118
00119 protected:
00123 virtual int
00124 init_ORB (int& argc, char *argv []);
00125
00126
00127
00129 bool m_isInitialized;
00130
00132 bool m_isProtected;
00133
00135 bool m_blockTermination;
00136
00138 CORBA::ORB_var m_orb;
00139
00141 LoggingProxy &m_logProxy;
00142
00144 CORBA::String_var m_ior;
00145
00147 T handler;
00148 };
00149
00150 template <typename T>
00151 ACSDaemonServiceImpl<T>::ACSDaemonServiceImpl (LoggingProxy &logProxy, bool isProtected) :
00152 m_isInitialized(false), m_logProxy(logProxy)
00153 {
00154
00155
00156 m_isInitialized = true;
00157
00158 m_isProtected = isProtected;
00159
00160 m_blockTermination = false;
00161
00162 ACS_CHECK_LOGGER;
00163
00164 Logging::Logger::setGlobalLogger(getNamedLogger(handler.getName()));
00165
00166 handler.setService(this);
00167 }
00168
00169 template <typename T>
00170 ACSDaemonServiceImpl<T>::~ACSDaemonServiceImpl (void)
00171 {
00172 }
00173
00174 template <typename T>
00175 int ACSDaemonServiceImpl<T>::startup (int argc, char *argv[])
00176 {
00177 ACS_SHORT_LOG ((LM_INFO, "Starting up the %s...", handler.getName().c_str()));
00178
00179
00180 if (init_ORB (argc, argv) != 0)
00181 {
00182 return -1;
00183 }
00184
00185
00186 if (!ACSError::init(m_orb.in()))
00187 {
00188 ACS_SHORT_LOG ((LM_ERROR, "Failed to initalize the ACS Error System."));
00189 return -1;
00190 }
00191
00192 ACS_SHORT_LOG ((LM_INFO, "%s is initialized.", handler.getName().c_str()));
00193
00194 return 0;
00195 }
00196
00197 template <typename T>
00198 int ACSDaemonServiceImpl<T>::run (void)
00199 {
00200 ACS_SHORT_LOG ((LM_INFO, "%s is up and running...", handler.getName().c_str()));
00201
00202
00203 try
00204 {
00205 handler.initialize(m_orb.in());
00206
00207
00208
00209 ORBTask task (this->m_orb.in(), &m_logProxy);
00210 const int m_serverThreads = 5;
00211
00212 if (task.activate (THR_NEW_LWP | THR_JOINABLE, m_serverThreads) == 0)
00213
00214 task.thr_mgr()->wait ();
00215 else
00216 {
00217
00218 ACS_LOG(LM_RUNTIME_CONTEXT, "ACSDaemonServiceImpl<T>::run", (LM_INFO, "Failed to activate CORBA ORB request handler threads..."));
00219 return -1;
00220 }
00221
00222 }
00223 catch(...)
00224 {
00225 return -1;
00226 }
00227
00228 return 0;
00229 }
00230
00231 template <typename T>
00232 void ACSDaemonServiceImpl<T>::shutdown (bool wait_for_completition)
00233 {
00234 if (!m_blockTermination)
00235 {
00236 ACS_SHORT_LOG ((LM_INFO, "Stopping the %s...", this->getName().c_str()));
00237 m_blockTermination=true;
00238
00239 if (!CORBA::is_nil (m_orb.in ()))
00240 {
00241 handler.dispose(m_orb.in());
00242 this->m_orb->shutdown (wait_for_completition);
00243 }
00244
00245 ACSError::done();
00246 }
00247 }
00248
00249 template <typename T>
00250 int ACSDaemonServiceImpl<T>::init_ORB (int& argc, char *argv [])
00251 {
00252 m_orb = CORBA::ORB_init(argc, argv, "TAO");
00253
00254 try
00255 {
00256
00257 CORBA::Object_var obj = m_orb->resolve_initial_references("RootPOA");
00258 PortableServer::POA_var root_poa = PortableServer::POA::_narrow(obj.in());
00259 PortableServer::POAManager_var poa_manager = root_poa->the_POAManager();
00260
00261
00262 CORBA::PolicyList policy_list;
00263 policy_list.length(5);
00264 policy_list[0] = root_poa->create_request_processing_policy(PortableServer::USE_DEFAULT_SERVANT);
00265 policy_list[1] = root_poa->create_id_uniqueness_policy(PortableServer::MULTIPLE_ID);
00266 policy_list[2] = root_poa->create_id_assignment_policy(PortableServer::USER_ID);
00267 policy_list[3] = root_poa->create_servant_retention_policy(PortableServer::NON_RETAIN);
00268 policy_list[4] = root_poa->create_lifespan_policy(PortableServer::PERSISTENT);
00269
00270
00271 PortableServer::POA_var poa = root_poa->create_POA(handler.getType().c_str(), poa_manager.in(), policy_list);
00272
00273
00274 for (CORBA::ULong i = 0; i < policy_list.length(); ++i)
00275 {
00276 CORBA::Policy_ptr policy = policy_list[i];
00277 policy->destroy();
00278 }
00279
00280
00281 poa->set_servant(&handler);
00282
00283
00284 PortableServer::ObjectId_var oid = PortableServer::string_to_ObjectId(handler.getType().c_str());
00285 obj = poa->create_reference_with_id (oid.in(), handler._interface_repository_id());
00286 m_ior = m_orb->object_to_string(obj.in());
00287
00288
00289 CORBA::Object_var table_object = m_orb->resolve_initial_references("IORTable");
00290 IORTable::Table_var adapter = IORTable::Table::_narrow(table_object.in());
00291
00292 if (CORBA::is_nil(adapter.in()))
00293 {
00294 ACS_SHORT_LOG ((LM_ERROR, "Nil IORTable"));
00295 return -1;
00296 }
00297 else
00298 {
00299 adapter->bind(handler.getType().c_str(), m_ior.in());
00300 }
00301
00302
00303 poa_manager->activate();
00304
00305 ACS_SHORT_LOG((LM_INFO, "%s is waiting for incoming requests.", handler.getName().c_str()));
00306
00307 }
00308 catch( CORBA::Exception &ex )
00309 {
00310 ACE_PRINT_EXCEPTION (ex, "EXCEPTION CAUGHT");
00311 return -1;
00312 }
00313
00314 return 0;
00315 }
00316
00324 template <typename T>
00325 class acsDaemonImpl
00326 {
00327
00328 public:
00329
00333 acsDaemonImpl(int argc, char *argv[]);
00334
00338 ~acsDaemonImpl();
00339
00343 void usage(const char *argv);
00344
00348 int run();
00349
00353 void shutdown();
00354
00355 private:
00356
00358 ACSDaemonServiceImpl<T> *service;
00359
00361 ACE_CString iorFile;
00362
00364 ACE_CString ORBEndpoint;
00365
00367 int nargc;
00368 char** nargv;
00369
00371 LoggingProxy *m_logger;
00372 };
00373
00374
00376 static struct option long_options[] = {
00377 {"help", no_argument, 0, 'h'},
00378 {"outfile", required_argument, 0, 'o'},
00379 {"ORBEndpoint", required_argument, 0, 'O'},
00380 {"unprotected", no_argument, 0, 'u'},
00381 {0, 0, 0, '\0'}};
00382
00383 template <typename T>
00384 void acsDaemonImpl<T>::usage(const char *argv)
00385 {
00386 ACE_OS::printf ("\n\tusage: %s {-h} [-O iiop://ip:port] [-o iorfile]\n", argv);
00387 ACE_OS::printf ("\t -h, --help show this help message\n");
00388 ACE_OS::printf ("\t -O, --ORBEndpoint ORB end point\n");
00389 ACE_OS::printf ("\t -o, --outfile IOR output file\n");
00390 ACE_OS::printf ("\t -u, --unprotected start in unprotected mode\n");
00391 }
00392
00393 template <typename T>
00394 acsDaemonImpl<T>::acsDaemonImpl(int argc, char *argv[])
00395 {
00396 nargc = 0;
00397 nargv = 0;
00398 service = 0;
00399 m_logger = 0;
00400 bool unprotected = false;
00401
00402
00403
00404 int c;
00405 for(;;)
00406 {
00407 int option_index = 0;
00408 c = getopt_long (argc, argv, "ho:O:u",
00409 long_options, &option_index);
00410 if (c==-1) break;
00411 switch(c)
00412 {
00413 case 'h':
00414 usage(argv[0]);
00415 return;
00416 case 'o':
00417 iorFile = optarg;
00418 break;
00419 case 'O':
00420 ORBEndpoint = optarg;
00421 break;
00422 case 'u':
00423 unprotected = true;
00424 break;
00425 default:
00426 ACE_OS::printf("Ignoring unrecognized option %s",
00427 argv[option_index]);
00428 }
00429 }
00430
00431
00432
00433 const char* hostName = ACSPorts::getIP();
00434
00435
00436 char * acsLogFileEnv = ACE_OS::getenv("ACS_LOG_FILE");
00437 ACE_CString acsLogFileValue(acsLogFileEnv);
00438 ACE_OS::setenv("ACS_LOG_FILE", "/dev/null", 1);
00439
00440
00441 LoggingProxy::ProcessName(argv[0]);
00442 LoggingProxy::ThreadName("main");
00443 ACE_Log_Msg::instance()->local_host(hostName);
00444 m_logger = new LoggingProxy (0, 0, 31, 0);
00445
00446 LoggingProxy::init (m_logger);
00447
00448
00449 if (acsLogFileEnv)
00450 ACE_OS::setenv("ACS_LOG_FILE", acsLogFileValue.c_str(), 1);
00451 else
00452 ACE_OS::unsetenv("ACS_LOG_FILE");
00453
00454
00455 service = new ACSDaemonServiceImpl<T>(*m_logger, !unprotected);
00456
00457
00458 ACE_CString argStr;
00459
00460 if(ORBEndpoint.length()<=0)
00461 {
00462 argStr = ACE_CString("-ORBEndpoint iiop://") + hostName + ":";
00463 argStr = argStr + service->getPort().c_str();
00464 }
00465 else
00466 {
00467 argStr = ACE_CString("-ORBEndpoint ") + ORBEndpoint;
00468 }
00469
00470 ACS_SHORT_LOG((LM_INFO, "Command line is: %s", argStr.c_str()));
00471 ACE_OS::string_to_argv ((ACE_TCHAR*)argStr.c_str(), nargc, nargv);
00472 }
00473
00474 template <typename T>
00475 acsDaemonImpl<T>::~acsDaemonImpl()
00476 {
00477 if (service != 0) delete service;
00478 if (m_logger != 0)
00479 {
00480 LoggingProxy::done();
00481 delete m_logger;
00482 }
00483 }
00484
00485
00486 template <typename T>
00487 int acsDaemonImpl<T>::run()
00488 {
00489 ACS_TRACE("acsDaemonImpl<T>::run");
00490 if (!service || !service->isInitialized())
00491 {
00492 return -1;
00493 }
00494 try
00495 {
00496 if (service->startup (nargc, nargv) != 0)
00497 {
00498 return -1;
00499 }
00500
00501
00502 if (iorFile.length() > 0)
00503 {
00504 FILE *output_file = ACE_OS::fopen (iorFile.c_str(), "w");
00505 if (output_file == 0)
00506 {
00507 ACS_SHORT_LOG ((LM_ERROR, "Cannot open output file '%s' to write IOR.", iorFile.c_str()));
00508 return -1;
00509 }
00510
00511 int result = ACE_OS::fprintf (output_file, "%s", service->getIOR());
00512 if (result < 0)
00513 {
00514 ACS_SHORT_LOG ((LM_ERROR, "ACE_OS::fprintf failed to write IOR."));
00515 return -1;
00516 }
00517
00518 ACE_OS::fclose (output_file);
00519 ACS_SHORT_LOG((LM_INFO, "%s IOR has been written into file '%s'.", service->getName().c_str(), iorFile.c_str()));
00520 }
00521
00522
00523 if (service->run () == -1)
00524 {
00525 this->shutdown ();
00526 ACS_SHORT_LOG ((LM_ERROR, "Failed to run the %s.", service->getName().c_str()));
00527 return 1;
00528 }
00529 }
00530 catch(...)
00531 {
00532 ACS_SHORT_LOG((LM_ERROR, "Failed to start the %s.", service->getName().c_str()));
00533 return 1;
00534 }
00535
00536
00537 this->shutdown();
00538
00539 ACS_SHORT_LOG ((LM_INFO, "%s stopped.", service->getName().c_str()));
00540
00541 return 0;
00542 }
00543
00544 template <typename T>
00545 void acsDaemonImpl<T>::shutdown()
00546 {
00547 service->shutdown(true);
00548 }
00549
00550 #endif