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
00492 protected:
00497 Logging::Logger::LoggerSmartPtr
00498 getLogger() {return m_logger;}
00499
00500
00501 private:
00502
00508 int parseArgs (int argc, char *argv[]);
00509
00511 void showUsage(int argc, char *argv[]);
00512
00524 ContainerServices* instantiateContainerServices(
00525 maci::Handle h,
00526 ACE_CString& name,
00527 ACE_CString& type,
00528 PortableServer::POA_ptr poa);
00529
00531 const char * m_pid_file_name;
00532
00534 const char * m_manager_ref;
00535
00536
00537 const char * m_container_name;
00538
00539
00540 static ContainerImpl * m_container;
00541
00543 static LibraryManager * m_dllmgr;
00544
00546 static LoggingProxy * m_loggerProxy;
00547
00548 #ifndef MAKE_VXWORKS
00549
00550 LogThrottleAlarmImpl* m_logThrottleAlarm_p;
00551 #endif
00552
00553 static int m_logLevelRefresh;
00554 static int m_logLevelConfigure;
00555
00557 MACIServantManager * m_servant_mgr;
00558
00560 cdb::Table * m_database;
00561
00562
00563 maci::Container_var m_container_ref;
00564
00565
00566
00567
00568 CORBA::ORB_var orb;
00569 PortableServer::POAManager_var poaManager;
00570 PortableServer::POA_var poaRoot;
00571 PortableServer::POA_var poaContainer;
00572 PortableServer::POA_var poaPersistent;
00573 PortableServer::POA_var poaTransient;
00574
00576 static CORBA::ULong m_invocationTimeout;
00577
00579 maci::Manager_var m_manager;
00580
00582 maci::Handle m_handle;
00583
00586 int m_status;
00587
00589 bool m_shutdown;
00590
00592 struct ContainerComponentInfo
00593 {
00594 int lib;
00595 maci::ComponentInfo info;
00596 };
00597
00598 typedef ACE_Hash_Map_Manager <maci::Handle, ContainerComponentInfo, ACE_Recursive_Thread_Mutex> COMPONENT_HASH_MAP;
00599 typedef ACE_Hash_Map_Iterator <maci::Handle, ContainerComponentInfo, ACE_Recursive_Thread_Mutex> COMPONENT_HASH_MAP_ITER;
00600 typedef ACE_Hash_Map_Entry <maci::Handle, ContainerComponentInfo> COMPONENT_HASH_MAP_ENTRY;
00601
00603 COMPONENT_HASH_MAP m_activeComponents;
00604
00605
00606 typedef ACE_Unbounded_Set <maci::Handle> COMPONENT_LIST;
00607
00609 COMPONENT_LIST m_activeComponentList;
00610
00612 maci::HandleSeq m_componentShutdownOrder;
00613
00615 bool initializeCORBA(int &argc, char *argv[]);
00616
00618 bool doneCORBA();
00619 public:
00621 CORBA::Object_ptr activateCORBAObject(PortableServer::Servant srvnt,
00622 const char * name);
00623
00625 bool deactivateCORBAObject(PortableServer::Servant servant);
00626
00628 bool deactivateCORBAObject(CORBA::Object_ptr servant);
00629 private:
00631 int loadDLL(const char * bame);
00632
00634 maci::Manager_ptr resolveManager(int nSecTimeout);
00635
00636
00637 void logout ();
00638
00639
00640 ACE_CString m_dbPrefix;
00641
00642
00643 ACE_CString m_dbRootPrefix;
00644
00645
00646 int m_argc;
00647
00648
00649 int m_fullargc;
00650
00651
00652 char** m_argv;
00653
00655 int m_shutdownAction;
00656
00658 bool m_hasIFR;
00659
00661 bool m_recovery;
00662
00663
00664
00665
00666
00668 ACE_SYNCH_MUTEX m_shutdownMutex;
00669
00671 ACE_SYNCH_CONDITION m_shutdownDone;
00672
00674 bool m_shutdownDoneSignaled;
00675
00677 int m_serverThreads;
00678
00680 bool m_dynamicContainer;
00681
00683 ContainerServices *m_containerServices;
00684
00686 maci::ContainerThreadHook m_containerThreadHook;
00687
00689 Logging::Logger::LoggerSmartPtr m_logger;
00690
00691
00692 Logging::LoggingConfigurable::LogLevels m_defaultLogLevels;
00693
00694
00695 std::map<std::string, Logging::LoggingConfigurable::LogLevels> m_logLevels;
00696
00697
00698 maci::ExecutionId m_executionId;
00699
00700
00701 ACS::Time m_startTime;
00702
00703
00704 unsigned long cacheSize;
00705 unsigned long minCachePriority;
00706 unsigned long maxCachePriority;
00707 unsigned int flushPeriodSeconds;
00708 int maxLogsPerSecond;
00709
00710
00711 MethodRequestThreadPool* m_methodRequestThreadPool;
00712
00713
00714 std::auto_ptr<acsalarm::AlarmSourceThread> m_alarmSourceThread_ap;
00715
00716 const acsalarm::AlarmSourceThread* getAlarmSourceThread() {
00717 if (m_alarmSourceThread_ap.get()==NULL)
00718 {
00719 m_alarmSourceThread_ap=std::auto_ptr<acsalarm::AlarmSourceThread>(new acsalarm::AlarmSourceThread());
00720 }
00721 return m_alarmSourceThread_ap.get();
00722 }
00723 };
00724
00726
00729 template<class T>
00730 T* ContainerImpl::getComponent(const char *name, const char *domain, bool activate)
00731 {
00732 T* object = T::_nil();
00733
00734 if(!name)
00735 {
00736 ACS_SHORT_LOG((LM_DEBUG, "Name parameter is null."));
00737 return T::_nil();
00738 }
00739
00743 ACE_CString curl = "curl://";
00744 if (domain)
00745 curl += domain;
00746
00747 curl += ACE_CString("/");
00748
00749 curl += name;
00750
00751 ACS_SHORT_LOG((LM_DEBUG, "Getting component: '%s'.", curl.c_str()));
00752
00753
00754 while (m_handle==0)
00755 {
00756 ACS_SHORT_LOG((LM_DEBUG, "Waiting for m_handle"));
00757 ACE_OS::sleep(1);
00758 }
00759
00760 try
00761 {
00762 CORBA::Object_var obj = m_manager->get_component(m_handle, curl.c_str(), activate);
00763
00764 if (CORBA::is_nil(obj.in()))
00765 {
00766 ACS_SHORT_LOG((LM_DEBUG, "Failed to create '%s'.", curl.c_str()));
00767 maciErrType::CannotGetComponentExImpl ex(__FILE__, __LINE__,
00768 "ContainerImpl::getComponent<>");
00769 ex.setCURL(name);
00770 ex.log();
00771
00772 return T::_nil();
00773 }
00774 object = T::_narrow(obj.in());
00775
00776 return object;
00777 }
00778 catch(maciErrType::ComponentNotAlreadyActivatedEx &_ex)
00779 {
00780 maciErrType::CannotGetComponentExImpl ex(_ex, __FILE__, __LINE__,
00781 "maci::ContainerImpl::getComponent<>");
00782 ex.setCURL(name);
00783 ex.log();
00785 return T::_nil();
00786 }
00787 catch(maciErrType::ComponentConfigurationNotFoundEx &_ex)
00788 {
00789 maciErrType::CannotGetComponentExImpl ex(_ex, __FILE__, __LINE__,
00790 "maci::ContainerImpl::getComponent<>");
00791 ex.setCURL(name);
00792 ex.log();
00794 return T::_nil();
00795 }
00796 catch( CORBA::SystemException &_ex )
00797 {
00798 ACSErrTypeCommon::CORBAProblemExImpl corbaProblemEx(__FILE__, __LINE__,
00799 "ContainerServices::getComponent<>");
00800 corbaProblemEx.setMinor(_ex.minor());
00801 corbaProblemEx.setCompletionStatus(_ex.completed());
00802 corbaProblemEx.setInfo(_ex._info().c_str());
00803 maciErrType::CannotGetComponentExImpl ex(corbaProblemEx, __FILE__, __LINE__,
00804 "ContainerImpl::getComponent<>");
00805 ex.setCURL(name);
00806 ex.log();
00808 return T::_nil();
00809 }
00810 catch(...)
00811 {
00812 ACSErrTypeCommon::UnexpectedExceptionExImpl uex(__FILE__, __LINE__,
00813 "ContainerImpl::getComponent<>");
00814 maciErrType::CannotGetComponentExImpl ex(uex, __FILE__, __LINE__,
00815 "ContainerImpl::getComponent<>");
00816 ex.setCURL(name);
00817 ex.log();
00819 return T::_nil();
00820 }
00821 }
00823
00826 template<class T>
00827 T* ContainerImpl::getService(const char *name, const char *domain, bool activate)
00828 {
00829 ACS_TRACE("ContainerImpl::getService<>");
00830 T* object = T::_nil();
00831
00832 if(!name)
00833 {
00834 ACSErrTypeCommon::NullPointerExImpl nullEx(__FILE__, __LINE__,
00835 "ContainerImpl::getService<>");
00836 nullEx.setVariable("(parameter) name");
00837 maciErrType::CannotGetServiceExImpl ex(nullEx, __FILE__, __LINE__,
00838 "ContainerImpl::getService<>");
00839 ex.setCURL("NULL");
00840 throw ex;
00841 }
00842
00843
00844 ACE_CString curl = "curl://";
00845 if (domain)
00846 curl += domain;
00847
00848 curl += ACE_CString("/");
00849
00850 curl += name;
00851
00852 ACS_SHORT_LOG((LM_DEBUG, "Getting service: '%s'.", curl.c_str()));
00853
00854
00855 while (m_handle==0)
00856 {
00857 ACS_SHORT_LOG((LM_DEBUG, "Waiting for m_handle"));
00858 ACE_OS::sleep(1);
00859 }
00860
00861 try
00862 {
00863 CORBA::Object_var obj = m_manager->get_service(m_handle, curl.c_str(), activate);
00864
00865 if (CORBA::is_nil(obj.in()))
00866 {
00867 maciErrType::CannotGetServiceExImpl ex(__FILE__, __LINE__,
00868 "ContainerImpl::getService<>");
00869 ex.setCURL(name);
00870 throw ex;
00871 }
00872 object = T::_narrow(obj.in());
00873
00874 return object;
00875 }
00876 catch(maciErrType::CannotGetComponentEx &_ex)
00877 {
00878 maciErrType::CannotGetServiceExImpl ex(_ex, __FILE__, __LINE__,
00879 "ContainerImpl::getService<>");
00880 ex.setCURL(name);
00881 throw ex;
00882 }
00883 catch(maciErrType::ComponentNotAlreadyActivatedEx &_ex)
00884 {
00885 maciErrType::CannotGetServiceExImpl ex(_ex, __FILE__, __LINE__,
00886 "ContainerImpl::getService<>");
00887 ex.setCURL(name);
00888 throw ex;
00889 }
00890 catch(maciErrType::ComponentConfigurationNotFoundEx &_ex)
00891 {
00892 maciErrType::CannotGetServiceExImpl ex(_ex, __FILE__, __LINE__,
00893 "ContainerImpl::getService<>");
00894 ex.setCURL(name);
00895 throw ex;
00896 }
00897 catch( CORBA::SystemException &_ex )
00898 {
00899 ACSErrTypeCommon::CORBAProblemExImpl corbaProblemEx(__FILE__, __LINE__,
00900 "ContainerImpl::getService<>");
00901 corbaProblemEx.setMinor(_ex.minor());
00902 corbaProblemEx.setCompletionStatus(_ex.completed());
00903 corbaProblemEx.setInfo(_ex._info().c_str());
00904 maciErrType::CannotGetServiceExImpl ex(corbaProblemEx, __FILE__, __LINE__,
00905 "ContainerImpl::getService<>");
00906 ex.setCURL(name);
00907 throw ex;
00908 }
00909 catch(...)
00910 {
00911 ACSErrTypeCommon::UnexpectedExceptionExImpl uex(__FILE__, __LINE__,
00912 "ContainerImpl::getService<>");
00913 maciErrType::CannotGetServiceExImpl ex(uex, __FILE__, __LINE__,
00914 "ContainerImpl::getService<>");
00915 ex.setCURL(name);
00916 throw ex;
00917 }
00918 }
00919
00920 };
00921
00922 #endif // maciContainerImpl_h
00923