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 <AlarmSourceThread.h>
00032
00033 #include <ace/Synch.h>
00034 #include <ace/Hash_Map_Manager.h>
00035 #include <ace/Unbounded_Set.h>
00036
00037 #include <acsContainerServices.h>
00038 #include "maciContainerThreadHook.h"
00039 #ifndef MAKE_VXWORKS
00040 #include "maciLogThrottleAlarmImpl.h"
00041 #endif
00042
00043 #include <map>
00044
00045 #include <ace/Activation_Queue.h>
00046 #include <ace/Method_Request.h>
00047 #include <ace/Task.h>
00048 #include <ace/Auto_Ptr.h>
00049 #include <ACSErrTypeOK.h>
00050
00051
00052
00054 #define CONTAINER_RELOAD 0
00055
00056 #define CONTAINER_REBOOT 1
00057
00058 #define CONTAINER_EXIT 2
00059
00060 namespace maci {
00061
00062
00073 typedef PortableServer::Servant (*ConstructComponentFunc)(
00074 maci::Handle h,
00075 const char * name,
00076 const char * type,
00077 ContainerServices * containerServices
00078 );
00079
00080
00081
00082
00083 class ContainerServices;
00084 class MACIServantManager;
00085 class LibraryManager;
00086
00087
00088
00089 class MethodRequestThreadPool : public ACE_Task_Base, public Logging::Loggable
00090 {
00091 public:
00092 MethodRequestThreadPool (int n_threads = 1);
00093
00094 virtual int svc (void);
00095
00096 int enqueue (ACE_Method_Request *request);
00097
00098 void shutdown();
00099
00100 private:
00101 ACE_Activation_Queue activation_queue_;
00102
00103 int m_threads;
00104 };
00105
00106
00134 class maci_EXPORT ContainerImpl :
00135 public virtual POA_maci::Container,
00136 public virtual PortableServer::RefCountServantBase
00137 {
00138 public:
00139
00143 static ContainerImpl * getContainer()
00144 {
00145 return m_container;
00146 }
00147
00150 maci::Container_ptr getContainerCORBAProxy()
00151 {
00152 return m_container_ref.ptr();
00153 }
00154
00157 static LoggingProxy * getLoggerProxy()
00158 {
00159 return m_loggerProxy;
00160 }
00161
00164 char * getProcessName()
00165 {
00166 return m_argv[0];
00167 }
00168
00170 ContainerImpl();
00171
00173 virtual ~ContainerImpl();
00174
00175
00198 maci::Manager_ptr getManager();
00199
00200 bool init(int argc, char *argv[]);
00201 bool connect();
00202 bool run();
00203 bool done();
00204
00206 int getStatus() { return m_status; }
00208 void setStatus(int status) { m_status = status; }
00209
00211 static void initThread(const char * threadName = 0);
00212
00214 static void doneThread();
00215
00217 void etherealizeComponent(const char * id, PortableServer::Servant servant);
00218
00221 int getShutdownAction() { return m_shutdownAction; }
00222
00225 void setShutdownAction(int action) { m_shutdownAction=action; }
00226
00229 maci::Handle getHandle() { return m_handle; }
00230
00233 PortableServer::POA_var getContainerPOA() { return poaContainer; }
00234
00237 PortableServer::POAManager_var getPOAManager() { return poaManager; }
00238
00241 ContainerServices* getContainerServices() { return m_containerServices; }
00242
00245 CORBA::ORB_var getContainerORB() { return orb; }
00246
00247
00248
00249
00250
00256 virtual ::maci::Handle get_handle ();
00257
00281 virtual maci::ComponentInfo * activate_component (maci::Handle h,
00282 maci::ExecutionId execution_id,
00283 const char * name,
00284 const char * exe,
00285 const char * type
00286 );
00287
00288
00289 virtual void activate_component_async(maci::Handle, maci::ExecutionId, const char*, const char*, const char*, maci::CBComponentInfo*, const ACS::CBDescIn&);
00290
00300 virtual void deactivate_component (maci::Handle h
00301 );
00302
00308 virtual CORBA::Object_ptr restart_component (maci::Handle h
00309 );
00310
00315 virtual void shutdown (CORBA::ULong action
00316 );
00317
00325 virtual maci::ComponentInfoSeq * get_component_info (const maci::HandleSeq & h
00326 );
00327
00333 virtual char * name ();
00334
00339 virtual void disconnect ();
00340
00348 virtual maci::AuthenticationData * authenticate (maci::ExecutionId execution_id, const char * question
00349 );
00350
00356 virtual void message (CORBA::Short type,
00357 const char * message
00358 );
00359
00366 virtual void taggedmessage (CORBA::Short type,
00367 CORBA::Short tag,
00368 const char * message
00369 );
00370
00375 virtual void components_available (const maci::ComponentInfoSeq & components
00376 );
00377
00382 virtual void components_unavailable (const maci::stringSeq & component_names
00383 );
00384
00389 virtual void set_component_shutdown_order(const maci::HandleSeq & h
00390 );
00391
00402 virtual CORBA::Object_ptr get_object(const char *name,
00403 const char *domain,
00404 bool activate
00405 );
00406
00416 template<class T>
00417 T* get_object(const char *name, const char *domain, bool activate)
00418 {
00419 return getComponent<T>(name, domain, activate);
00420 }
00421
00430 template<class T>
00431 T* getComponent(const char *name, const char *domain, bool activate);
00432
00442 template<class T>
00443 T* getService(const char *name, const char *domain, bool activate);
00444
00454 void releaseComponent(const char *name);
00455
00464 virtual CORBA::Boolean ping ();
00465
00470 virtual Logging::LoggingConfigurable::LogLevels get_default_logLevels();
00471
00472 virtual void set_default_logLevels(const Logging::LoggingConfigurable::LogLevels&);
00473
00474 virtual Logging::stringSeq* get_logger_names();
00475
00476
00477
00478
00479 virtual Logging::LoggingConfigurable::LogLevels get_logLevels(const char*);
00480
00481
00482
00483
00484 virtual void set_logLevels(const char*, const Logging::LoggingConfigurable::LogLevels&);
00485
00486 virtual void refresh_logging_config();
00487
00488 static void configureLogger(const std::string& loggerName);
00489
00490 void loadLoggerConfiguration(const std::string& loggerName);
00491
00495 virtual Logging::ACSLogStatistics::logStatsInformationSeq* get_statistics_logger_configuration();
00496
00497
00498
00499 virtual Logging::ACSLogStatistics::LogStatsInformation* get_statistics_logger_configuration_byname(const char* logger_name);
00500
00501
00502
00503
00504 virtual void set_statistics_logger_configuration_byname(const char* logger_name, const Logging::ACSLogStatistics::LogStatsInformation& statsInformation);
00505
00506 protected:
00511 Logging::Logger::LoggerSmartPtr
00512 getLogger() {return m_logger;}
00513
00514
00515 private:
00516
00522 int parseArgs (int argc, char *argv[]);
00523
00525 void showUsage(int argc, char *argv[]);
00526
00538 ContainerServices* instantiateContainerServices(
00539 maci::Handle h,
00540 ACE_CString& name,
00541 ACE_CString& type,
00542 PortableServer::POA_ptr poa);
00543
00545 const char * m_pid_file_name;
00546
00548 const char * m_manager_ref;
00549
00550
00551 const char * m_container_name;
00552
00553
00554 static ContainerImpl * m_container;
00555
00557 static LibraryManager * m_dllmgr;
00558
00560 static LoggingProxy * m_loggerProxy;
00561
00562 #ifndef MAKE_VXWORKS
00563
00564 LogThrottleAlarmImpl* m_logThrottleAlarm_p;
00565 #endif
00566
00567 static int m_logLevelRefresh;
00568 static int m_logLevelConfigure;
00569
00571 MACIServantManager * m_servant_mgr;
00572
00574 cdb::Table * m_database;
00575
00576
00577 maci::Container_var m_container_ref;
00578
00579
00580
00581
00582 CORBA::ORB_var orb;
00583 PortableServer::POAManager_var poaManager;
00584 PortableServer::POA_var poaRoot;
00585 PortableServer::POA_var poaContainer;
00586 PortableServer::POA_var poaPersistent;
00587 PortableServer::POA_var poaTransient;
00588
00590 static CORBA::ULong m_invocationTimeout;
00591
00593 maci::Manager_var m_manager;
00594
00596 maci::Handle m_handle;
00597
00600 int m_status;
00601
00603 bool m_shutdown;
00604
00606 struct ContainerComponentInfo
00607 {
00608 int lib;
00609 maci::ComponentInfo info;
00610 };
00611
00612 typedef ACE_Hash_Map_Manager <maci::Handle, ContainerComponentInfo, ACE_Recursive_Thread_Mutex> COMPONENT_HASH_MAP;
00613 typedef ACE_Hash_Map_Iterator <maci::Handle, ContainerComponentInfo, ACE_Recursive_Thread_Mutex> COMPONENT_HASH_MAP_ITER;
00614 typedef ACE_Hash_Map_Entry <maci::Handle, ContainerComponentInfo> COMPONENT_HASH_MAP_ENTRY;
00615
00617 COMPONENT_HASH_MAP m_activeComponents;
00618
00619
00620 typedef ACE_Unbounded_Set <maci::Handle> COMPONENT_LIST;
00621
00623 COMPONENT_LIST m_activeComponentList;
00624
00626 maci::HandleSeq m_componentShutdownOrder;
00627
00629 bool initializeCORBA(int &argc, char *argv[]);
00630
00632 bool doneCORBA();
00633 public:
00635 CORBA::Object_ptr activateCORBAObject(PortableServer::Servant srvnt,
00636 const char * name);
00637
00639 bool deactivateCORBAObject(PortableServer::Servant servant);
00640
00642 bool deactivateCORBAObject(CORBA::Object_ptr servant);
00643 private:
00645 int loadDLL(const char * bame);
00646
00648 maci::Manager_ptr resolveManager(int nSecTimeout);
00649
00650
00651 void logout ();
00652
00653
00654 ACE_CString m_dbPrefix;
00655
00656
00657 ACE_CString m_dbRootPrefix;
00658
00659
00660 int m_argc;
00661
00662
00663 int m_fullargc;
00664
00665
00666 char** m_argv;
00667
00669 int m_shutdownAction;
00670
00672 bool m_hasIFR;
00673
00675 bool m_recovery;
00676
00677
00678
00679
00680
00682 ACE_SYNCH_MUTEX m_shutdownMutex;
00683
00685 ACE_SYNCH_CONDITION m_shutdownDone;
00686
00688 bool m_shutdownDoneSignaled;
00689
00691 int m_serverThreads;
00692
00694 bool m_dynamicContainer;
00695
00697 ContainerServices *m_containerServices;
00698
00700 maci::ContainerThreadHook m_containerThreadHook;
00701
00703 Logging::Logger::LoggerSmartPtr m_logger;
00704
00705
00706 Logging::LoggingConfigurable::LogLevels m_defaultLogLevels;
00707
00708
00709 std::map<std::string, Logging::LoggingConfigurable::LogLevels> m_logLevels;
00710
00711
00712 maci::ExecutionId m_executionId;
00713
00714
00715 ACS::Time m_startTime;
00716
00717
00718 unsigned long cacheSize;
00719 unsigned long minCachePriority;
00720 unsigned long maxCachePriority;
00721 unsigned int flushPeriodSeconds;
00722 int maxLogsPerSecond;
00723
00724
00725 MethodRequestThreadPool* m_methodRequestThreadPool;
00726
00727
00728 std::auto_ptr<acsalarm::AlarmSourceThread> m_alarmSourceThread_ap;
00729
00730 const acsalarm::AlarmSourceThread* getAlarmSourceThread() {
00731 if (m_alarmSourceThread_ap.get()==NULL)
00732 {
00733 m_alarmSourceThread_ap=std::auto_ptr<acsalarm::AlarmSourceThread>(new acsalarm::AlarmSourceThread());
00734 }
00735 return m_alarmSourceThread_ap.get();
00736 }
00737 };
00738
00740
00743 template<class T>
00744 T* ContainerImpl::getComponent(const char *name, const char *domain, bool activate)
00745 {
00746 T* object = T::_nil();
00747
00748 if(!name)
00749 {
00750 ACS_SHORT_LOG((LM_DEBUG, "Name parameter is null."));
00751 return T::_nil();
00752 }
00753
00757 ACE_CString curl = "curl://";
00758 if (domain)
00759 curl += domain;
00760
00761 curl += ACE_CString("/");
00762
00763 curl += name;
00764
00765 ACS_SHORT_LOG((LM_DEBUG, "Getting component: '%s'.", curl.c_str()));
00766
00767
00768 while (m_handle==0)
00769 {
00770 ACS_SHORT_LOG((LM_DEBUG, "Waiting for m_handle"));
00771 ACE_OS::sleep(1);
00772 }
00773
00774 try
00775 {
00776 CORBA::Object_var obj = m_manager->get_component(m_handle, curl.c_str(), activate);
00777
00778 if (CORBA::is_nil(obj.in()))
00779 {
00780 ACS_SHORT_LOG((LM_DEBUG, "Failed to create '%s'.", curl.c_str()));
00781 maciErrType::CannotGetComponentExImpl ex(__FILE__, __LINE__,
00782 "ContainerImpl::getComponent<>");
00783 ex.setCURL(name);
00784 ex.log();
00785
00786 return T::_nil();
00787 }
00788 object = T::_narrow(obj.in());
00789
00790 return object;
00791 }
00792 catch(maciErrType::ComponentNotAlreadyActivatedEx &_ex)
00793 {
00794 maciErrType::CannotGetComponentExImpl ex(_ex, __FILE__, __LINE__,
00795 "maci::ContainerImpl::getComponent<>");
00796 ex.setCURL(name);
00797 ex.log();
00799 return T::_nil();
00800 }
00801 catch(maciErrType::ComponentConfigurationNotFoundEx &_ex)
00802 {
00803 maciErrType::CannotGetComponentExImpl ex(_ex, __FILE__, __LINE__,
00804 "maci::ContainerImpl::getComponent<>");
00805 ex.setCURL(name);
00806 ex.log();
00808 return T::_nil();
00809 }
00810 catch( CORBA::SystemException &_ex )
00811 {
00812 ACSErrTypeCommon::CORBAProblemExImpl corbaProblemEx(__FILE__, __LINE__,
00813 "ContainerServices::getComponent<>");
00814 corbaProblemEx.setMinor(_ex.minor());
00815 corbaProblemEx.setCompletionStatus(_ex.completed());
00816 corbaProblemEx.setInfo(_ex._info().c_str());
00817 maciErrType::CannotGetComponentExImpl ex(corbaProblemEx, __FILE__, __LINE__,
00818 "ContainerImpl::getComponent<>");
00819 ex.setCURL(name);
00820 ex.log();
00822 return T::_nil();
00823 }
00824 catch(...)
00825 {
00826 ACSErrTypeCommon::UnexpectedExceptionExImpl uex(__FILE__, __LINE__,
00827 "ContainerImpl::getComponent<>");
00828 maciErrType::CannotGetComponentExImpl ex(uex, __FILE__, __LINE__,
00829 "ContainerImpl::getComponent<>");
00830 ex.setCURL(name);
00831 ex.log();
00833 return T::_nil();
00834 }
00835 }
00837
00840 template<class T>
00841 T* ContainerImpl::getService(const char *name, const char *domain, bool activate)
00842 {
00843 ACS_TRACE("ContainerImpl::getService<>");
00844 T* object = T::_nil();
00845
00846 if(!name)
00847 {
00848 ACSErrTypeCommon::NullPointerExImpl nullEx(__FILE__, __LINE__,
00849 "ContainerImpl::getService<>");
00850 nullEx.setVariable("(parameter) name");
00851 maciErrType::CannotGetServiceExImpl ex(nullEx, __FILE__, __LINE__,
00852 "ContainerImpl::getService<>");
00853 ex.setCURL("NULL");
00854 throw ex;
00855 }
00856
00857
00858 ACE_CString curl = "curl://";
00859 if (domain)
00860 curl += domain;
00861
00862 curl += ACE_CString("/");
00863
00864 curl += name;
00865
00866 ACS_SHORT_LOG((LM_DEBUG, "Getting service: '%s'.", curl.c_str()));
00867
00868
00869 while (m_handle==0)
00870 {
00871 ACS_SHORT_LOG((LM_DEBUG, "Waiting for m_handle"));
00872 ACE_OS::sleep(1);
00873 }
00874
00875 try
00876 {
00877 CORBA::Object_var obj = m_manager->get_service(m_handle, curl.c_str(), activate);
00878
00879 if (CORBA::is_nil(obj.in()))
00880 {
00881 maciErrType::CannotGetServiceExImpl ex(__FILE__, __LINE__,
00882 "ContainerImpl::getService<>");
00883 ex.setCURL(name);
00884 throw ex;
00885 }
00886 object = T::_narrow(obj.in());
00887
00888 return object;
00889 }
00890 catch(maciErrType::CannotGetComponentEx &_ex)
00891 {
00892 maciErrType::CannotGetServiceExImpl ex(_ex, __FILE__, __LINE__,
00893 "ContainerImpl::getService<>");
00894 ex.setCURL(name);
00895 throw ex;
00896 }
00897 catch(maciErrType::ComponentNotAlreadyActivatedEx &_ex)
00898 {
00899 maciErrType::CannotGetServiceExImpl ex(_ex, __FILE__, __LINE__,
00900 "ContainerImpl::getService<>");
00901 ex.setCURL(name);
00902 throw ex;
00903 }
00904 catch(maciErrType::ComponentConfigurationNotFoundEx &_ex)
00905 {
00906 maciErrType::CannotGetServiceExImpl ex(_ex, __FILE__, __LINE__,
00907 "ContainerImpl::getService<>");
00908 ex.setCURL(name);
00909 throw ex;
00910 }
00911 catch( CORBA::SystemException &_ex )
00912 {
00913 ACSErrTypeCommon::CORBAProblemExImpl corbaProblemEx(__FILE__, __LINE__,
00914 "ContainerImpl::getService<>");
00915 corbaProblemEx.setMinor(_ex.minor());
00916 corbaProblemEx.setCompletionStatus(_ex.completed());
00917 corbaProblemEx.setInfo(_ex._info().c_str());
00918 maciErrType::CannotGetServiceExImpl ex(corbaProblemEx, __FILE__, __LINE__,
00919 "ContainerImpl::getService<>");
00920 ex.setCURL(name);
00921 throw ex;
00922 }
00923 catch(...)
00924 {
00925 ACSErrTypeCommon::UnexpectedExceptionExImpl uex(__FILE__, __LINE__,
00926 "ContainerImpl::getService<>");
00927 maciErrType::CannotGetServiceExImpl ex(uex, __FILE__, __LINE__,
00928 "ContainerImpl::getService<>");
00929 ex.setCURL(name);
00930 throw ex;
00931 }
00932 }
00933
00934 };
00935
00936 #endif // maciContainerImpl_h
00937