00001 #ifndef maciContainerImpl_h
00002 #define maciContainerImpl_h
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <acsutil.h>
00023 #include <maciExport.h>
00024
00025 #include <maciS.h>
00026
00027 #include <cdb.h>
00028
00029 #include <logging.h>
00030
00031 #include <ace/Synch.h>
00032 #include <ace/Hash_Map_Manager.h>
00033 #include <ace/Unbounded_Set.h>
00034
00035 #include <acsContainerServices.h>
00036 #include "maciContainerThreadHook.h"
00037
00038 #include <map>
00039
00040 #include <ace/Activation_Queue.h>
00041 #include <ace/Method_Request.h>
00042 #include <ace/Task.h>
00043 #include <ace/Auto_Ptr.h>
00044 #include <ACSErrTypeOK.h>
00045
00046
00047
00049 #define CONTAINER_RELOAD 0
00050
00051 #define CONTAINER_REBOOT 1
00052
00053 #define CONTAINER_EXIT 2
00054
00055 namespace maci {
00056
00057
00068 typedef PortableServer::Servant (*ConstructComponentFunc)(
00069 maci::Handle h,
00070 const char * name,
00071 const char * type,
00072 ContainerServices * containerServices
00073 );
00074
00075
00076
00077
00078 class ContainerServices;
00079 class MACIServantManager;
00080 class LibraryManager;
00081
00082
00083
00084 class MethodRequestThreadPool : public ACE_Task_Base
00085 {
00086 public:
00087 MethodRequestThreadPool (int n_threads = 1);
00088
00089 virtual int svc (void);
00090
00091 int enqueue (ACE_Method_Request *request);
00092
00093 void shutdown();
00094
00095 protected:
00100 Logging::Logger::LoggerSmartPtr
00101 getLogger() {return m_logger;}
00102
00103 private:
00104 ACE_Activation_Queue activation_queue_;
00105
00106 int m_threads;
00107
00109 Logging::Logger::LoggerSmartPtr m_logger;
00110 };
00111
00112
00140 class maci_EXPORT ContainerImpl :
00141 public virtual POA_maci::Container,
00142 public virtual PortableServer::RefCountServantBase
00143 {
00144 public:
00145
00149 static ContainerImpl * getContainer()
00150 {
00151 return m_container;
00152 }
00153
00156 maci::Container_ptr getContainerCORBAProxy()
00157 {
00158 return m_container_ref.ptr();
00159 }
00160
00163 static LoggingProxy * getLoggerProxy()
00164 {
00165 return m_loggerProxy;
00166 }
00167
00170 char * getProcessName()
00171 {
00172 return m_argv[0];
00173 }
00174
00176 ContainerImpl();
00177
00179 virtual ~ContainerImpl();
00180
00181
00204 maci::Manager_ptr getManager();
00205
00206 bool init(int argc, char *argv[]);
00207 bool connect();
00208 bool run();
00209 bool done();
00210
00212 int getStatus() { return m_status; }
00214 void setStatus(int status) { m_status = status; }
00215
00217 static void initThread(const char * threadName = 0);
00218
00220 static void doneThread();
00221
00223 void etherealizeComponent(const char * id, PortableServer::Servant servant);
00224
00227 int getShutdownAction() { return m_shutdownAction; }
00228
00231 void setShutdownAction(int action) { m_shutdownAction=action; }
00232
00235 maci::Handle getHandle() { return m_handle; }
00236
00239 PortableServer::POA_var getContainerPOA() { return poaContainer; }
00240
00243 PortableServer::POAManager_var getPOAManager() { return poaManager; }
00244
00247 ContainerServices* getContainerServices() { return m_containerServices; }
00248
00251 CORBA::ORB_var getContainerORB() { return orb; }
00252
00253
00254
00255
00256
00280 virtual maci::ComponentInfo * activate_component (maci::Handle h,
00281 maci::ExecutionId execution_id,
00282 const char * name,
00283 const char * exe,
00284 const char * type
00285 );
00286
00287
00288 virtual void activate_component_async(maci::Handle, maci::ExecutionId, const char*, const char*, const char*, maci::CBComponentInfo*, const ACS::CBDescIn&);
00289
00299 virtual void deactivate_component (maci::Handle h
00300 );
00301
00307 virtual CORBA::Object_ptr restart_component (maci::Handle h
00308 );
00309
00314 virtual void shutdown (CORBA::ULong action
00315 );
00316
00324 virtual maci::ComponentInfoSeq * get_component_info (const maci::HandleSeq & h
00325 );
00326
00332 virtual char * name ();
00333
00338 virtual void disconnect ();
00339
00347 virtual maci::AuthenticationData * authenticate (maci::ExecutionId execution_id, const char * question
00348 );
00349
00355 virtual void message (CORBA::Short type,
00356 const char * message
00357 );
00358
00365 virtual void taggedmessage (CORBA::Short type,
00366 CORBA::Short tag,
00367 const char * message
00368 );
00369
00374 virtual void components_available (const maci::ComponentInfoSeq & components
00375 );
00376
00381 virtual void components_unavailable (const maci::stringSeq & component_names
00382 );
00383
00388 virtual void set_component_shutdown_order(const maci::HandleSeq & h
00389 );
00390
00401 virtual CORBA::Object_ptr get_object(const char *name,
00402 const char *domain,
00403 bool activate
00404 );
00405
00415 template<class T>
00416 T* get_object(const char *name, const char *domain, bool activate)
00417 {
00418 return getComponent<T>(name, domain, activate);
00419 }
00420
00429 template<class T>
00430 T* getComponent(const char *name, const char *domain, bool activate);
00431
00441 template<class T>
00442 T* getService(const char *name, const char *domain, bool activate);
00443
00453 void releaseComponent(const char *name);
00454
00463 virtual CORBA::Boolean ping ();
00464
00469 virtual maci::LoggingConfigurable::LogLevels get_default_logLevels();
00470
00471 virtual void set_default_logLevels(const maci::LoggingConfigurable::LogLevels&);
00472
00473 virtual maci::stringSeq* get_logger_names();
00474
00475
00476
00477
00478 virtual maci::LoggingConfigurable::LogLevels get_logLevels(const char*);
00479
00480
00481
00482
00483 virtual void set_logLevels(const char*, const maci::LoggingConfigurable::LogLevels&);
00484
00485 virtual void refresh_logging_config();
00486
00487 static void configureLogger(const std::string& loggerName);
00488
00489 void loadLoggerConfiguration(const std::string& loggerName);
00490
00491 protected:
00496 Logging::Logger::LoggerSmartPtr
00497 getLogger() {return m_logger;}
00498
00499
00500 private:
00501
00507 int parseArgs (int argc, char *argv[]);
00508
00510 void showUsage(int argc, char *argv[]);
00511
00523 ContainerServices* instantiateContainerServices(
00524 maci::Handle h,
00525 ACE_CString& name,
00526 ACE_CString& type,
00527 PortableServer::POA_ptr poa);
00528
00530 const char * m_pid_file_name;
00531
00533 const char * m_manager_ref;
00534
00535
00536 const char * m_container_name;
00537
00538
00539 static ContainerImpl * m_container;
00540
00542 static LibraryManager * m_dllmgr;
00543
00545 static LoggingProxy * m_loggerProxy;
00546
00547 static int m_logLevelRefresh;
00548 static int m_logLevelConfigure;
00549
00551 MACIServantManager * m_servant_mgr;
00552
00554 cdb::Table * m_database;
00555
00556
00557 maci::Container_var m_container_ref;
00558
00559
00560
00561
00562 CORBA::ORB_var orb;
00563 PortableServer::POAManager_var poaManager;
00564 PortableServer::POA_var poaRoot;
00565 PortableServer::POA_var poaContainer;
00566 PortableServer::POA_var poaPersistent;
00567 PortableServer::POA_var poaTransient;
00568
00570 static CORBA::ULong m_invocationTimeout;
00571
00573 maci::Manager_var m_manager;
00574
00576 maci::Handle m_handle;
00577
00580 int m_status;
00581
00583 bool m_shutdown;
00584
00586 struct ContainerComponentInfo
00587 {
00588 int lib;
00589 maci::ComponentInfo info;
00590 };
00591
00592 typedef ACE_Hash_Map_Manager <maci::Handle, ContainerComponentInfo, ACE_Recursive_Thread_Mutex> COMPONENT_HASH_MAP;
00593 typedef ACE_Hash_Map_Iterator <maci::Handle, ContainerComponentInfo, ACE_Recursive_Thread_Mutex> COMPONENT_HASH_MAP_ITER;
00594 typedef ACE_Hash_Map_Entry <maci::Handle, ContainerComponentInfo> COMPONENT_HASH_MAP_ENTRY;
00595
00597 COMPONENT_HASH_MAP m_activeComponents;
00598
00599
00600 typedef ACE_Unbounded_Set <maci::Handle> COMPONENT_LIST;
00601
00603 COMPONENT_LIST m_activeComponentList;
00604
00606 maci::HandleSeq m_componentShutdownOrder;
00607
00609 bool initializeCORBA(int &argc, char *argv[]);
00610
00612 bool doneCORBA();
00613 public:
00615 CORBA::Object_ptr activateCORBAObject(PortableServer::Servant srvnt,
00616 const char * name);
00617
00619 bool deactivateCORBAObject(PortableServer::Servant servant);
00620
00622 bool deactivateCORBAObject(CORBA::Object_ptr servant);
00623 private:
00625 int loadDLL(const char * bame);
00626
00628 maci::Manager_ptr resolveManager(int nSecTimeout);
00629
00630
00631 void logout ();
00632
00633
00634 ACE_CString m_dbPrefix;
00635
00636
00637 ACE_CString m_dbRootPrefix;
00638
00639
00640 int m_argc;
00641
00642
00643 int m_fullargc;
00644
00645
00646 char** m_argv;
00647
00649 int m_shutdownAction;
00650
00652 bool m_hasIFR;
00653
00655 bool m_recovery;
00656
00657
00658
00659
00660
00662 ACE_SYNCH_MUTEX m_shutdownMutex;
00663
00665 ACE_SYNCH_CONDITION m_shutdownDone;
00666
00668 bool m_shutdownDoneSignaled;
00669
00671 int m_serverThreads;
00672
00674 bool m_dynamicContainer;
00675
00677 ContainerServices *m_containerServices;
00678
00680 maci::ContainerThreadHook m_containerThreadHook;
00681
00683 Logging::Logger::LoggerSmartPtr m_logger;
00684
00685
00686 maci::LoggingConfigurable::LogLevels m_defaultLogLevels;
00687
00688
00689 std::map<std::string, maci::LoggingConfigurable::LogLevels> m_logLevels;
00690
00691
00692 maci::ExecutionId m_executionId;
00693
00694
00695 ACS::Time m_startTime;
00696
00697
00698 unsigned long cacheSize;
00699 unsigned long minCachePriority;
00700 unsigned long maxCachePriority;
00701 unsigned int flushPeriodSeconds;
00702 int maxLogsPerSecond;
00703
00704
00705 MethodRequestThreadPool* m_methodRequestThreadPool;
00706 };
00707
00709
00712 template<class T>
00713 T* ContainerImpl::getComponent(const char *name, const char *domain, bool activate)
00714 {
00715 T* object = T::_nil();
00716
00717 if(!name)
00718 {
00719 ACS_SHORT_LOG((LM_DEBUG, "Name parameter is null."));
00720 return T::_nil();
00721 }
00722
00726 ACE_CString curl = "curl://";
00727 if (domain)
00728 curl += domain;
00729
00730 curl += ACE_CString("/");
00731
00732 curl += name;
00733
00734 ACS_SHORT_LOG((LM_DEBUG, "Getting component: '%s'.", curl.c_str()));
00735
00736
00737 while (m_handle==0)
00738 {
00739 ACS_SHORT_LOG((LM_DEBUG, "Waiting for m_handle"));
00740 ACE_OS::sleep(1);
00741 }
00742
00743 try
00744 {
00745 CORBA::Object_var obj = m_manager->get_component(m_handle, curl.c_str(), activate);
00746
00747 if (CORBA::is_nil(obj.in()))
00748 {
00749 ACS_SHORT_LOG((LM_DEBUG, "Failed to create '%s'.", curl.c_str()));
00750 maciErrType::CannotGetComponentExImpl ex(__FILE__, __LINE__,
00751 "ContainerImpl::getComponent<>");
00752 ex.setCURL(name);
00753 ex.log();
00754
00755 return T::_nil();
00756 }
00757 object = T::_narrow(obj.in());
00758
00759 return object;
00760 }
00761 catch(maciErrType::ComponentNotAlreadyActivatedEx &_ex)
00762 {
00763 maciErrType::CannotGetComponentExImpl ex(_ex, __FILE__, __LINE__,
00764 "maci::ContainerImpl::getComponent<>");
00765 ex.setCURL(name);
00766 ex.log();
00768 return T::_nil();
00769 }
00770 catch(maciErrType::ComponentConfigurationNotFoundEx &_ex)
00771 {
00772 maciErrType::CannotGetComponentExImpl ex(_ex, __FILE__, __LINE__,
00773 "maci::ContainerImpl::getComponent<>");
00774 ex.setCURL(name);
00775 ex.log();
00777 return T::_nil();
00778 }
00779 catch( CORBA::SystemException &_ex )
00780 {
00781 ACSErrTypeCommon::CORBAProblemExImpl corbaProblemEx(__FILE__, __LINE__,
00782 "ContainerServices::getComponent<>");
00783 corbaProblemEx.setMinor(_ex.minor());
00784 corbaProblemEx.setCompletionStatus(_ex.completed());
00785 corbaProblemEx.setInfo(_ex._info().c_str());
00786 maciErrType::CannotGetComponentExImpl ex(corbaProblemEx, __FILE__, __LINE__,
00787 "ContainerImpl::getComponent<>");
00788 ex.setCURL(name);
00789 ex.log();
00791 return T::_nil();
00792 }
00793 catch(...)
00794 {
00795 ACSErrTypeCommon::UnexpectedExceptionExImpl uex(__FILE__, __LINE__,
00796 "ContainerImpl::getComponent<>");
00797 maciErrType::CannotGetComponentExImpl ex(uex, __FILE__, __LINE__,
00798 "ContainerImpl::getComponent<>");
00799 ex.setCURL(name);
00800 ex.log();
00802 return T::_nil();
00803 }
00804 }
00806
00809 template<class T>
00810 T* ContainerImpl::getService(const char *name, const char *domain, bool activate)
00811 {
00812 ACS_TRACE("ContainerImpl::getService<>");
00813 T* object = T::_nil();
00814
00815 if(!name)
00816 {
00817 ACSErrTypeCommon::NullPointerExImpl nullEx(__FILE__, __LINE__,
00818 "ContainerImpl::getService<>");
00819 nullEx.setVariable("(parameter) name");
00820 maciErrType::CannotGetServiceExImpl ex(nullEx, __FILE__, __LINE__,
00821 "ContainerImpl::getService<>");
00822 ex.setCURL("NULL");
00823 throw ex;
00824 }
00825
00826
00827 ACE_CString curl = "curl://";
00828 if (domain)
00829 curl += domain;
00830
00831 curl += ACE_CString("/");
00832
00833 curl += name;
00834
00835 ACS_SHORT_LOG((LM_DEBUG, "Getting service: '%s'.", curl.c_str()));
00836
00837
00838 while (m_handle==0)
00839 {
00840 ACS_SHORT_LOG((LM_DEBUG, "Waiting for m_handle"));
00841 ACE_OS::sleep(1);
00842 }
00843
00844 try
00845 {
00846 CORBA::Object_var obj = m_manager->get_service(m_handle, curl.c_str(), activate);
00847
00848 if (CORBA::is_nil(obj.in()))
00849 {
00850 maciErrType::CannotGetServiceExImpl ex(__FILE__, __LINE__,
00851 "ContainerImpl::getService<>");
00852 ex.setCURL(name);
00853 throw ex;
00854 }
00855 object = T::_narrow(obj.in());
00856
00857 return object;
00858 }
00859 catch(maciErrType::CannotGetComponentEx &_ex)
00860 {
00861 maciErrType::CannotGetServiceExImpl ex(_ex, __FILE__, __LINE__,
00862 "ContainerImpl::getService<>");
00863 ex.setCURL(name);
00864 throw ex;
00865 }
00866 catch(maciErrType::ComponentNotAlreadyActivatedEx &_ex)
00867 {
00868 maciErrType::CannotGetServiceExImpl ex(_ex, __FILE__, __LINE__,
00869 "ContainerImpl::getService<>");
00870 ex.setCURL(name);
00871 throw ex;
00872 }
00873 catch(maciErrType::ComponentConfigurationNotFoundEx &_ex)
00874 {
00875 maciErrType::CannotGetServiceExImpl ex(_ex, __FILE__, __LINE__,
00876 "ContainerImpl::getService<>");
00877 ex.setCURL(name);
00878 throw ex;
00879 }
00880 catch( CORBA::SystemException &_ex )
00881 {
00882 ACSErrTypeCommon::CORBAProblemExImpl corbaProblemEx(__FILE__, __LINE__,
00883 "ContainerImpl::getService<>");
00884 corbaProblemEx.setMinor(_ex.minor());
00885 corbaProblemEx.setCompletionStatus(_ex.completed());
00886 corbaProblemEx.setInfo(_ex._info().c_str());
00887 maciErrType::CannotGetServiceExImpl ex(corbaProblemEx, __FILE__, __LINE__,
00888 "ContainerImpl::getService<>");
00889 ex.setCURL(name);
00890 throw ex;
00891 }
00892 catch(...)
00893 {
00894 ACSErrTypeCommon::UnexpectedExceptionExImpl uex(__FILE__, __LINE__,
00895 "ContainerImpl::getService<>");
00896 maciErrType::CannotGetServiceExImpl ex(uex, __FILE__, __LINE__,
00897 "ContainerImpl::getService<>");
00898 ex.setCURL(name);
00899 throw ex;
00900 }
00901 }
00902
00903 };
00904
00905 #endif // maciContainerImpl_h
00906