mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-31 01:24:19 +02:00
Refactored the Component class.
This commit is contained in:
parent
bcb1b23d9f
commit
4814fed13a
@ -60,14 +60,6 @@ Application::~Application(void)
|
|||||||
{
|
{
|
||||||
m_ShuttingDown = true;
|
m_ShuttingDown = true;
|
||||||
|
|
||||||
/* stop all components */
|
|
||||||
Component::Ptr component;
|
|
||||||
BOOST_FOREACH(tie(tuples::ignore, component), m_Components) {
|
|
||||||
component->Stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Components.clear();
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
@ -101,6 +93,8 @@ void Application::RunEventLoop(void)
|
|||||||
|
|
||||||
Event::ProcessEvents(boost::get_system_time() + boost::posix_time::seconds(sleep));
|
Event::ProcessEvents(boost::get_system_time() + boost::posix_time::seconds(sleep));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component::UnloadAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -112,103 +106,6 @@ void Application::Shutdown(void)
|
|||||||
m_ShuttingDown = true;
|
m_ShuttingDown = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads a component from a shared library.
|
|
||||||
*
|
|
||||||
* @param path The path of the component library.
|
|
||||||
* @param componentConfig The configuration for the component.
|
|
||||||
* @returns The component.
|
|
||||||
*/
|
|
||||||
Component::Ptr Application::LoadComponent(const string& path,
|
|
||||||
const ConfigObject::Ptr& componentConfig)
|
|
||||||
{
|
|
||||||
Component::Ptr component;
|
|
||||||
Component *(*pCreateComponent)();
|
|
||||||
|
|
||||||
assert(Application::IsMainThread());
|
|
||||||
|
|
||||||
Logger::Write(LogInformation, "base", "Loading component '" + path + "'");
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
HMODULE hModule = LoadLibrary(path.c_str());
|
|
||||||
|
|
||||||
if (hModule == NULL)
|
|
||||||
throw_exception(Win32Exception("LoadLibrary('" + path + "') failed", GetLastError()));
|
|
||||||
#else /* _WIN32 */
|
|
||||||
lt_dlhandle hModule = lt_dlopen(path.c_str());
|
|
||||||
|
|
||||||
if (hModule == NULL) {
|
|
||||||
throw_exception(runtime_error("Could not load module '" + path + "': " + lt_dlerror()));
|
|
||||||
}
|
|
||||||
#endif /* _WIN32 */
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
pCreateComponent = (CreateComponentFunction)GetProcAddress(hModule,
|
|
||||||
"CreateComponent");
|
|
||||||
#else /* _WIN32 */
|
|
||||||
# ifdef __GNUC__
|
|
||||||
/* suppress compiler warning for void * cast */
|
|
||||||
__extension__
|
|
||||||
# endif
|
|
||||||
pCreateComponent = (CreateComponentFunction)lt_dlsym(hModule,
|
|
||||||
"CreateComponent");
|
|
||||||
#endif /* _WIN32 */
|
|
||||||
|
|
||||||
if (pCreateComponent == NULL)
|
|
||||||
throw_exception(runtime_error("Loadable module does not contain "
|
|
||||||
"CreateComponent function"));
|
|
||||||
|
|
||||||
component = Component::Ptr(pCreateComponent());
|
|
||||||
component->SetConfig(componentConfig);
|
|
||||||
RegisterComponent(component);
|
|
||||||
return component;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers a component object and starts it.
|
|
||||||
*
|
|
||||||
* @param component The component.
|
|
||||||
*/
|
|
||||||
void Application::RegisterComponent(const Component::Ptr& component)
|
|
||||||
{
|
|
||||||
m_Components[component->GetName()] = component;
|
|
||||||
|
|
||||||
component->Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unregisters a component object and stops it.
|
|
||||||
*
|
|
||||||
* @param component The component.
|
|
||||||
*/
|
|
||||||
void Application::UnregisterComponent(const Component::Ptr& component)
|
|
||||||
{
|
|
||||||
string name = component->GetName();
|
|
||||||
|
|
||||||
Logger::Write(LogInformation, "base", "Unloading component '" + name + "'");
|
|
||||||
map<string, Component::Ptr>::iterator i = m_Components.find(name);
|
|
||||||
if (i != m_Components.end())
|
|
||||||
m_Components.erase(i);
|
|
||||||
|
|
||||||
component->Stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds a loaded component by name.
|
|
||||||
*
|
|
||||||
* @param name The name of the component.
|
|
||||||
* @returns The component or a null pointer if the component could not be found.
|
|
||||||
*/
|
|
||||||
Component::Ptr Application::GetComponent(const string& name) const
|
|
||||||
{
|
|
||||||
map<string, Component::Ptr>::const_iterator i = m_Components.find(name);
|
|
||||||
|
|
||||||
if (i == m_Components.end())
|
|
||||||
return Component::Ptr();
|
|
||||||
|
|
||||||
return i->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the full path of the executable.
|
* Retrieves the full path of the executable.
|
||||||
*
|
*
|
||||||
@ -276,20 +173,6 @@ string Application::GetExePath(void) const
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a directory to the component search path.
|
|
||||||
*
|
|
||||||
* @param componentDirectory The directory.
|
|
||||||
*/
|
|
||||||
void Application::AddComponentSearchDir(const string& componentDirectory)
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
SetDllDirectory(componentDirectory.c_str());
|
|
||||||
#else /* _WIN32 */
|
|
||||||
lt_dladdsearchdir(componentDirectory.c_str());
|
|
||||||
#endif /* _WIN32 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the debugging mode of the application.
|
* Retrieves the debugging mode of the application.
|
||||||
*
|
*
|
||||||
|
@ -45,13 +45,6 @@ public:
|
|||||||
|
|
||||||
static void Shutdown(void);
|
static void Shutdown(void);
|
||||||
|
|
||||||
shared_ptr<Component> LoadComponent(const string& path,
|
|
||||||
const ConfigObject::Ptr& componentConfig);
|
|
||||||
void RegisterComponent(const shared_ptr<Component>& component);
|
|
||||||
void UnregisterComponent(const shared_ptr<Component>& component);
|
|
||||||
shared_ptr<Component> GetComponent(const string& name) const;
|
|
||||||
void AddComponentSearchDir(const string& componentDirectory);
|
|
||||||
|
|
||||||
static bool IsDebugging(void);
|
static bool IsDebugging(void);
|
||||||
|
|
||||||
static bool IsMainThread(void);
|
static bool IsMainThread(void);
|
||||||
@ -68,8 +61,6 @@ private:
|
|||||||
|
|
||||||
static bool m_ShuttingDown; /**< Whether the application is in the process of
|
static bool m_ShuttingDown; /**< Whether the application is in the process of
|
||||||
shutting down. */
|
shutting down. */
|
||||||
map< string, shared_ptr<Component> > m_Components; /**< Components that
|
|
||||||
were loaded by the application. */
|
|
||||||
vector<string> m_Arguments; /**< Command-line arguments */
|
vector<string> m_Arguments; /**< Command-line arguments */
|
||||||
FILE *m_PidFile; /**< The PID file */
|
FILE *m_PidFile; /**< The PID file */
|
||||||
static bool m_Debugging; /**< Whether debugging is enabled. */
|
static bool m_Debugging; /**< Whether debugging is enabled. */
|
||||||
|
@ -21,14 +21,152 @@
|
|||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
|
map<string, Component::Ptr> Component::m_Components;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the configuration for this component.
|
* Loads a component from a shared library.
|
||||||
*
|
*
|
||||||
* @param componentConfig The configuration.
|
* @param name The name of the component.
|
||||||
|
* @param componentConfig The configuration for the component.
|
||||||
*/
|
*/
|
||||||
void Component::SetConfig(const ConfigObject::Ptr& componentConfig)
|
void Component::Load(const string& name, const ConfigObject::Ptr& config)
|
||||||
{
|
{
|
||||||
m_Config = componentConfig;
|
assert(Application::IsMainThread());
|
||||||
|
|
||||||
|
string path;
|
||||||
|
#ifdef _WIN32
|
||||||
|
path = name + ".dll";
|
||||||
|
#else /* _WIN32 */
|
||||||
|
path = name + ".la";
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
Logger::Write(LogInformation, "base", "Loading component '" + name + "' (using library '" + path + "')");
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
HMODULE hModule = LoadLibrary(path.c_str());
|
||||||
|
|
||||||
|
if (hModule == NULL)
|
||||||
|
throw_exception(Win32Exception("LoadLibrary('" + path + "') failed", GetLastError()));
|
||||||
|
#else /* _WIN32 */
|
||||||
|
lt_dlhandle hModule = lt_dlopen(path.c_str());
|
||||||
|
|
||||||
|
if (hModule == NULL) {
|
||||||
|
throw_exception(runtime_error("Could not load module '" + path + "': " + lt_dlerror()));
|
||||||
|
}
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
CreateComponentFunction pCreateComponent;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
pCreateComponent = (CreateComponentFunction)GetProcAddress(hModule,
|
||||||
|
"CreateComponent");
|
||||||
|
#else /* _WIN32 */
|
||||||
|
# ifdef __GNUC__
|
||||||
|
/* suppress compiler warning for void * cast */
|
||||||
|
__extension__
|
||||||
|
# endif
|
||||||
|
pCreateComponent = (CreateComponentFunction)lt_dlsym(hModule,
|
||||||
|
"CreateComponent");
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
Component::Ptr component;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (pCreateComponent == NULL)
|
||||||
|
throw_exception(runtime_error("Loadable module does not contain "
|
||||||
|
"CreateComponent function"));
|
||||||
|
|
||||||
|
component = Component::Ptr(pCreateComponent());
|
||||||
|
|
||||||
|
if (!component)
|
||||||
|
throw_exception(runtime_error("CreateComponent function returned NULL."));
|
||||||
|
} catch (...) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
FreeLibrary(hModule);
|
||||||
|
#else /* _WIN32 */
|
||||||
|
lt_dlclose(hModule);
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
component->m_Name = name;
|
||||||
|
component->m_Config = config;
|
||||||
|
component->m_ModuleHandle = hModule;
|
||||||
|
|
||||||
|
try {
|
||||||
|
m_Components[name] = component;
|
||||||
|
component->Start();
|
||||||
|
} catch (...) {
|
||||||
|
m_Components.erase(name);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Component::Unload(const string& componentName)
|
||||||
|
{
|
||||||
|
map<string, Component::Ptr>::iterator it;
|
||||||
|
|
||||||
|
it = m_Components.find(componentName);
|
||||||
|
|
||||||
|
if (it == m_Components.end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Logger::Write(LogInformation, "base", "Unloading component '" + componentName + "'");
|
||||||
|
|
||||||
|
Component::Ptr component = it->second;
|
||||||
|
component->Stop();
|
||||||
|
|
||||||
|
m_Components.erase(it);
|
||||||
|
|
||||||
|
/** Unfortunatelly we can't safely unload the DLL/shared library
|
||||||
|
* here because there could still be objects that use the library. */
|
||||||
|
}
|
||||||
|
|
||||||
|
void Component::UnloadAll(void)
|
||||||
|
{
|
||||||
|
Logger::Write(LogInformation, "base", "Unloading all components");
|
||||||
|
|
||||||
|
while (!m_Components.empty()) {
|
||||||
|
string name = m_Components.begin()->first;
|
||||||
|
Unload(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a directory to the component search path.
|
||||||
|
*
|
||||||
|
* @param componentDirectory The directory.
|
||||||
|
*/
|
||||||
|
void Component::AddSearchDir(const string& componentDirectory)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
SetDllDirectory(componentDirectory.c_str());
|
||||||
|
#else /* _WIN32 */
|
||||||
|
lt_dladdsearchdir(componentDirectory.c_str());
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the Component class.
|
||||||
|
*/
|
||||||
|
Component::Component(void)
|
||||||
|
: m_ModuleHandle(0)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor for the Component class.
|
||||||
|
*/
|
||||||
|
Component::~Component(void)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the name of the component.
|
||||||
|
*
|
||||||
|
* @returns Name of the component.
|
||||||
|
*/
|
||||||
|
string Component::GetName(void) const
|
||||||
|
{
|
||||||
|
return m_Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,3 +178,19 @@ ConfigObject::Ptr Component::GetConfig(void) const
|
|||||||
{
|
{
|
||||||
return m_Config;
|
return m_Config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the component.
|
||||||
|
*/
|
||||||
|
void Component::Start(void)
|
||||||
|
{
|
||||||
|
/* Nothing to do in the default implementation. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops the component.
|
||||||
|
*/
|
||||||
|
void Component::Stop(void)
|
||||||
|
{
|
||||||
|
/* Nothing to do in the default implementation. */
|
||||||
|
}
|
||||||
|
@ -35,15 +35,35 @@ public:
|
|||||||
typedef shared_ptr<Component> Ptr;
|
typedef shared_ptr<Component> Ptr;
|
||||||
typedef weak_ptr<Component> WeakPtr;
|
typedef weak_ptr<Component> WeakPtr;
|
||||||
|
|
||||||
void SetConfig(const ConfigObject::Ptr& componentConfig);
|
Component(void);
|
||||||
|
virtual ~Component(void);
|
||||||
|
|
||||||
ConfigObject::Ptr GetConfig(void) const;
|
ConfigObject::Ptr GetConfig(void) const;
|
||||||
|
|
||||||
virtual string GetName(void) const = 0;
|
virtual void Start(void);
|
||||||
virtual void Start(void) = 0;
|
virtual void Stop(void);
|
||||||
virtual void Stop(void) = 0;
|
|
||||||
|
string GetName(void) const;
|
||||||
|
|
||||||
|
static void Load(const string& name, const ConfigObject::Ptr& config);
|
||||||
|
static void Unload(const Component::Ptr& component);
|
||||||
|
static void Unload(const string& componentName);
|
||||||
|
static void UnloadAll(void);
|
||||||
|
static Component::Ptr GetByName(const string& name);
|
||||||
|
static void AddSearchDir(const string& componentDirectory);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
string m_Name;
|
||||||
ConfigObject::Ptr m_Config;
|
ConfigObject::Ptr m_Config;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
HMODULE m_ModuleHandle;
|
||||||
|
#else /* _WIN32 */
|
||||||
|
lt_dlhandle m_ModuleHandle;
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
static map<string, Component::Ptr> m_Components; /**< Components that
|
||||||
|
were loaded by the application. */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef Component *(*CreateComponentFunction)(void);
|
typedef Component *(*CreateComponentFunction)(void);
|
||||||
|
@ -133,7 +133,7 @@ int IcingaApplication::Main(const vector<string>& args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
string componentDirectory = Utility::DirName(GetExePath()) + "/../lib/icinga2";
|
string componentDirectory = Utility::DirName(GetExePath()) + "/../lib/icinga2";
|
||||||
AddComponentSearchDir(componentDirectory);
|
Component::AddSearchDir(componentDirectory);
|
||||||
|
|
||||||
/* register handler for 'component' config objects */
|
/* register handler for 'component' config objects */
|
||||||
static ConfigObject::Set::Ptr componentObjects = boost::make_shared<ConfigObject::Set>(ConfigObject::GetAllObjects(), ConfigObject::MakeTypePredicate("component"));
|
static ConfigObject::Set::Ptr componentObjects = boost::make_shared<ConfigObject::Set>(ConfigObject::GetAllObjects(), ConfigObject::MakeTypePredicate("component"));
|
||||||
@ -219,16 +219,7 @@ void IcingaApplication::NewComponentHandler(const ConfigObject::Ptr& object)
|
|||||||
if (!object->IsLocal())
|
if (!object->IsLocal())
|
||||||
throw_exception(runtime_error("'component' objects must be 'local'"));
|
throw_exception(runtime_error("'component' objects must be 'local'"));
|
||||||
|
|
||||||
string path;
|
Component::Load(object->GetName(), object);
|
||||||
if (!object->GetProperty("path", &path)) {
|
|
||||||
#ifdef _WIN32
|
|
||||||
path = object->GetName() + ".dll";
|
|
||||||
#else /* _WIN32 */
|
|
||||||
path = object->GetName() + ".la";
|
|
||||||
#endif /* _WIN32 */
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadComponent(path, object);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void IcingaApplication::NewLogHandler(const ConfigObject::Ptr& object)
|
void IcingaApplication::NewLogHandler(const ConfigObject::Ptr& object)
|
||||||
@ -290,8 +281,7 @@ IcingaApplication::Ptr IcingaApplication::GetInstance(void)
|
|||||||
|
|
||||||
void IcingaApplication::DeletedComponentHandler(const ConfigObject::Ptr& object)
|
void IcingaApplication::DeletedComponentHandler(const ConfigObject::Ptr& object)
|
||||||
{
|
{
|
||||||
Component::Ptr component = GetComponent(object->GetName());
|
Component::Unload(object->GetName());
|
||||||
UnregisterComponent(component);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string IcingaApplication::GetCertificateFile(void) const
|
string IcingaApplication::GetCertificateFile(void) const
|
||||||
|
Loading…
x
Reference in New Issue
Block a user