Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

acsDaemonImpl.h

Go to the documentation of this file.
00001 #ifndef _ACS_DAEMON_IMPL_H_ 00002 #define _ACS_DAEMON_IMPL_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: acsDaemonImpl.h,v 1.5.2.2 2008/11/19 11:04:45 msekoran Exp $" 00025 * 00026 * who when what 00027 * -------- -------- ---------------------------------------------- 00028 * msekoran 2006-06-21 created 00029 * agrimstr 2007-11-07 refactored common daemon implementation code to 00030 * template classes 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 00053 template <typename T> 00054 class ACSDaemonServiceImpl { 00055 00056 public: 00057 00061 ACSDaemonServiceImpl(LoggingProxy &logProxy, bool isProtected); 00062 00066 virtual ~ACSDaemonServiceImpl(); 00067 00071 bool 00072 isInitialized() { return m_isInitialized; } 00073 00077 bool 00078 isProtected() { return m_isProtected; } 00079 00080 00084 std::string 00085 getPort() { return handler.getPort(); } 00086 00090 std::string 00091 getName() { return handler.getName(); } 00092 00096 int 00097 startup (int argc, char *argv[]); 00098 00103 int 00104 run (); 00105 00109 void 00110 shutdown (bool wait_for_completition); 00111 00115 const char* 00116 getIOR() const { return m_ior.in(); }; 00117 00118 protected: 00122 virtual int 00123 init_ORB (int& argc, char *argv []); 00124 00125 //--Common data members------------------------------------- 00126 00128 bool m_isInitialized; 00129 00131 bool m_isProtected; 00132 00134 bool m_blockTermination; 00135 00137 CORBA::ORB_var m_orb; 00138 00140 LoggingProxy &m_logProxy; 00141 00143 CORBA::String_var m_ior; 00144 00146 T handler; 00147 }; 00148 00149 template <typename T> 00150 ACSDaemonServiceImpl<T>::ACSDaemonServiceImpl (LoggingProxy &logProxy, bool isProtected) : 00151 m_isInitialized(false), m_logProxy(logProxy) 00152 { 00153 // noop here 00154 00155 m_isInitialized = true; 00156 00157 m_isProtected = isProtected; 00158 00159 m_blockTermination = false; 00160 00161 ACS_CHECK_LOGGER; 00162 // daemon is a standalone process, replace global logger with named logger 00163 Logging::Logger::setGlobalLogger(getNamedLogger(handler.getName())); 00164 00165 handler.setService(this); 00166 } 00167 00168 template <typename T> 00169 ACSDaemonServiceImpl<T>::~ACSDaemonServiceImpl (void) 00170 { 00171 } 00172 00173 template <typename T> 00174 int ACSDaemonServiceImpl<T>::startup (int argc, char *argv[]) 00175 { 00176 ACS_SHORT_LOG ((LM_INFO, "Starting up the %s...", handler.getName().c_str())); 00177 00178 // Initalize the ORB. 00179 if (init_ORB (argc, argv) != 0) 00180 { 00181 return -1; 00182 } 00183 00184 // Initialize AES. 00185 if (!ACSError::init(m_orb.in())) 00186 { 00187 ACS_SHORT_LOG ((LM_ERROR, "Failed to initalize the ACS Error System.")); 00188 return -1; 00189 } 00190 00191 ACS_SHORT_LOG ((LM_INFO, "%s is initialized.", handler.getName().c_str())); 00192 00193 return 0; 00194 } 00195 00196 template <typename T> 00197 int ACSDaemonServiceImpl<T>::run (void) 00198 { 00199 ACS_SHORT_LOG ((LM_INFO, "%s is up and running...", handler.getName().c_str())); 00200 00201 00202 try 00203 { 00204 handler.initialize(m_orb.in()); 00205 this->m_orb->run (); 00206 } 00207 catch(...) 00208 { 00209 return -1; 00210 } 00211 00212 return 0; 00213 } 00214 00215 template <typename T> 00216 void ACSDaemonServiceImpl<T>::shutdown (bool wait_for_completition) 00217 { 00218 if (!m_blockTermination) 00219 { 00220 ACS_SHORT_LOG ((LM_INFO, "Stopping the %s...", this->getName().c_str())); 00221 m_blockTermination=true; 00222 // shutdown the ORB. 00223 if (!CORBA::is_nil (m_orb.in ())) 00224 { 00225 handler.dispose(m_orb.in()); 00226 this->m_orb->shutdown (wait_for_completition); 00227 } 00228 // shutdown AES 00229 ACSError::done(); 00230 } 00231 } 00232 00233 template <typename T> 00234 int ACSDaemonServiceImpl<T>::init_ORB (int& argc, char *argv []) 00235 { 00236 m_orb = CORBA::ORB_init(argc, argv, "TAO"); 00237 00238 try 00239 { 00240 // get a reference to the RootPOA 00241 CORBA::Object_var obj = m_orb->resolve_initial_references("RootPOA"); 00242 PortableServer::POA_var root_poa = PortableServer::POA::_narrow(obj.in()); 00243 PortableServer::POAManager_var poa_manager = root_poa->the_POAManager(); 00244 00245 // create policies 00246 CORBA::PolicyList policy_list; 00247 policy_list.length(5); 00248 policy_list[0] = root_poa->create_request_processing_policy(PortableServer::USE_DEFAULT_SERVANT); 00249 policy_list[1] = root_poa->create_id_uniqueness_policy(PortableServer::MULTIPLE_ID); 00250 policy_list[2] = root_poa->create_id_assignment_policy(PortableServer::USER_ID); 00251 policy_list[3] = root_poa->create_servant_retention_policy(PortableServer::NON_RETAIN); 00252 policy_list[4] = root_poa->create_lifespan_policy(PortableServer::PERSISTENT); 00253 00254 // create a ACSDaemon POA with policies 00255 PortableServer::POA_var poa = root_poa->create_POA(handler.getType().c_str(), poa_manager.in(), policy_list); 00256 00257 // destroy policies 00258 for (CORBA::ULong i = 0; i < policy_list.length(); ++i) 00259 { 00260 CORBA::Policy_ptr policy = policy_list[i]; 00261 policy->destroy(); 00262 } 00263 00264 // set as default servant 00265 poa->set_servant(&handler); 00266 00267 // create reference 00268 PortableServer::ObjectId_var oid = PortableServer::string_to_ObjectId(handler.getType().c_str()); 00269 obj = poa->create_reference_with_id (oid.in(), handler._interface_repository_id()); 00270 m_ior = m_orb->object_to_string(obj.in()); 00271 00272 // bind to IOR table 00273 CORBA::Object_var table_object = m_orb->resolve_initial_references("IORTable"); 00274 IORTable::Table_var adapter = IORTable::Table::_narrow(table_object.in()); 00275 00276 if (CORBA::is_nil(adapter.in())) 00277 { 00278 ACS_SHORT_LOG ((LM_ERROR, "Nil IORTable")); 00279 return -1; 00280 } 00281 else 00282 { 00283 adapter->bind(handler.getType().c_str(), m_ior.in()); 00284 } 00285 00286 // activate POA 00287 poa_manager->activate(); 00288 00289 ACS_SHORT_LOG((LM_INFO, "%s is waiting for incoming requests.", handler.getName().c_str())); 00290 00291 } 00292 catch( CORBA::Exception &ex ) 00293 { 00294 ACE_PRINT_EXCEPTION (ex, "EXCEPTION CAUGHT"); 00295 return -1; 00296 } 00297 00298 return 0; 00299 } 00300 00308 template <typename T> 00309 class acsDaemonImpl 00310 { 00311 00312 public: 00313 00317 acsDaemonImpl(int argc, char *argv[]); 00318 00322 ~acsDaemonImpl(); 00323 00327 void usage(const char *argv); 00328 00332 int run(); 00333 00337 void shutdown(); 00338 00339 private: 00340 00342 ACSDaemonServiceImpl<T> *service; 00343 00345 ACE_CString iorFile; 00346 00348 ACE_CString ORBEndpoint; 00349 00351 int nargc; 00352 char** nargv; 00353 00355 LoggingProxy *m_logger; 00356 }; 00357 00358 00360 static struct option long_options[] = { 00361 {"help", no_argument, 0, 'h'}, 00362 {"outfile", required_argument, 0, 'o'}, 00363 {"ORBEndpoint", required_argument, 0, 'O'}, 00364 {"unprotected", no_argument, 0, 'u'}, 00365 {0, 0, 0, '\0'}}; 00366 00367 template <typename T> 00368 void acsDaemonImpl<T>::usage(const char *argv) 00369 { 00370 ACE_OS::printf ("\n\tusage: %s {-h} [-O iiop://ip:port] [-o iorfile]\n", argv); 00371 ACE_OS::printf ("\t -h, --help show this help message\n"); 00372 ACE_OS::printf ("\t -O, --ORBEndpoint ORB end point\n"); 00373 ACE_OS::printf ("\t -o, --outfile IOR output file\n"); 00374 ACE_OS::printf ("\t -u, --unprotected start in unprotected mode\n"); 00375 } 00376 00377 template <typename T> 00378 acsDaemonImpl<T>::acsDaemonImpl(int argc, char *argv[]) 00379 { 00380 nargc = 0; 00381 nargv = 0; 00382 service = 0; 00383 m_logger = 0; 00384 bool unprotected = false; 00385 00386 00387 // Extract and validate command line arguments 00388 int c; 00389 for(;;) 00390 { 00391 int option_index = 0; 00392 c = getopt_long (argc, argv, "ho:O:u", 00393 long_options, &option_index); 00394 if (c==-1) break; 00395 switch(c) 00396 { 00397 case 'h': 00398 usage(argv[0]); 00399 return; 00400 case 'o': 00401 iorFile = optarg; 00402 break; 00403 case 'O': 00404 ORBEndpoint = optarg; 00405 break; 00406 case 'u': 00407 unprotected = true; 00408 break; 00409 default: 00410 ACE_OS::printf("Ignoring unrecognized option %s", 00411 argv[option_index]); 00412 } 00413 } 00414 00415 // Host IP information is needed to initialize the logging system 00416 // and for ORBEndpoint creation 00417 const char* hostName = ACSPorts::getIP(); 00418 00419 // create logging proxy 00420 LoggingProxy::ProcessName(argv[0]); 00421 LoggingProxy::ThreadName("main"); 00422 ACE_Log_Msg::instance()->local_host(hostName); 00423 m_logger = new LoggingProxy (0, 0, 31, 0); 00424 00425 LoggingProxy::init (m_logger); 00426 00427 // Ready the service manager 00428 service = new ACSDaemonServiceImpl<T>(*m_logger, !unprotected); 00429 00430 // Generate the CORBA configuration for the service 00431 ACE_CString argStr; 00432 00433 if(ORBEndpoint.length()<=0) 00434 { 00435 argStr = ACE_CString("-ORBEndpoint iiop://") + hostName + ":"; 00436 argStr = argStr + service->getPort().c_str(); 00437 } 00438 else 00439 { 00440 argStr = ACE_CString("-ORBEndpoint ") + ORBEndpoint; 00441 } 00442 00443 ACS_SHORT_LOG((LM_INFO, "Command line is: %s", argStr.c_str())); 00444 ACE_OS::string_to_argv ((ACE_TCHAR*)argStr.c_str(), nargc, nargv); 00445 } 00446 00447 template <typename T> 00448 acsDaemonImpl<T>::~acsDaemonImpl() 00449 { 00450 if (service != 0) delete service; 00451 if (m_logger != 0) 00452 { 00453 LoggingProxy::done(); 00454 delete m_logger; 00455 } 00456 } 00457 00458 00459 template <typename T> 00460 int acsDaemonImpl<T>::run() 00461 { 00462 ACS_TRACE("acsDaemonImpl<T>::run"); 00463 if (!service || !service->isInitialized()) 00464 { 00465 return -1; 00466 } 00467 try 00468 { 00469 if (service->startup (nargc, nargv) != 0) 00470 { 00471 return -1; 00472 } 00473 00474 // write IOR to file, if necessary 00475 if (iorFile.length() > 0) 00476 { 00477 FILE *output_file = ACE_OS::fopen (iorFile.c_str(), "w"); 00478 if (output_file == 0) 00479 { 00480 ACS_SHORT_LOG ((LM_ERROR, "Cannot open output file '%s' to write IOR.", iorFile.c_str())); 00481 return -1; 00482 } 00483 00484 int result = ACE_OS::fprintf (output_file, "%s", service->getIOR()); 00485 if (result < 0) 00486 { 00487 ACS_SHORT_LOG ((LM_ERROR, "ACE_OS::fprintf failed to write IOR.")); 00488 return -1; 00489 } 00490 00491 ACE_OS::fclose (output_file); 00492 ACS_SHORT_LOG((LM_INFO, "%s IOR has been written into file '%s'.", service->getName().c_str(), iorFile.c_str())); 00493 } 00494 00495 // run, run, run... 00496 if (service->run () == -1) 00497 { 00498 this->shutdown (); 00499 ACS_SHORT_LOG ((LM_ERROR, "Failed to run the %s.", service->getName().c_str())); 00500 return 1; 00501 } 00502 } 00503 catch(...) 00504 { 00505 ACS_SHORT_LOG((LM_ERROR, "Failed to start the %s.", service->getName().c_str())); 00506 return 1; 00507 } 00508 00509 00510 this->shutdown(); 00511 00512 ACS_SHORT_LOG ((LM_INFO, "%s stopped.", service->getName().c_str())); 00513 00514 return 0; 00515 } 00516 00517 template <typename T> 00518 void acsDaemonImpl<T>::shutdown() 00519 { 00520 service->shutdown(true); 00521 } 00522 00523 #endif

Generated on Thu Apr 30 02:30:48 2009 for ACS C++ API by doxygen 1.3.8