Build fixes and code cleanup.

This commit is contained in:
Gunnar Beutner 2012-08-03 13:19:55 +02:00
parent ea77ebe6da
commit d789cee443
24 changed files with 295 additions and 190 deletions

View File

@ -94,6 +94,14 @@ void Application::RunEventLoop(void)
DynamicObject::FinishTx(); DynamicObject::FinishTx();
DynamicObject::BeginTx(); DynamicObject::BeginTx();
#ifdef _DEBUG
stringstream msgbuf;
msgbuf << "Active objects: " << Object::GetAliveObjects();
Logger::Write(LogInformation, "base", msgbuf.str());
Object::PrintMemoryProfile();
#endif /* _DEBUG */
} }
} }

View File

@ -34,7 +34,7 @@ Value Dictionary::Get(const String& key) const
it = m_Data.find(key); it = m_Data.find(key);
if (it == m_Data.end()) if (it == m_Data.end())
return Value(); return Empty;
return it->second; return it->second;
} }
@ -140,7 +140,7 @@ void Dictionary::Remove(const String& key)
m_Data.erase(it); m_Data.erase(it);
OnItemModified(key, Value()); OnItemModified(key, Empty);
} }
/** /**
@ -153,7 +153,7 @@ void Dictionary::Remove(Dictionary::Iterator it)
String key = it->first; String key = it->first;
m_Data.erase(it); m_Data.erase(it);
OnItemModified(key, Value()); OnItemModified(key, Empty);
} }
/** /**

View File

@ -168,11 +168,16 @@ void DynamicObject::RegisterAttribute(const String& name, DynamicAttributeType t
tt.first->second.Type = type; tt.first->second.Type = type;
} }
void DynamicObject::SetAttribute(const String& name, const Value& data) void DynamicObject::Set(const String& name, const Value& data)
{ {
InternalSetAttribute(name, data, GetCurrentTx()); InternalSetAttribute(name, data, GetCurrentTx());
} }
Value DynamicObject::Get(const String& name) const
{
return InternalGetAttribute(name);
}
void DynamicObject::InternalSetAttribute(const String& name, const Value& data, double tx, bool suppressEvent) void DynamicObject::InternalSetAttribute(const String& name, const Value& data, double tx, bool suppressEvent)
{ {
DynamicAttribute attr; DynamicAttribute attr;
@ -203,14 +208,9 @@ Value DynamicObject::InternalGetAttribute(const String& name) const
it = m_Attributes.find(name); it = m_Attributes.find(name);
if (it == m_Attributes.end()) if (it == m_Attributes.end())
return Value(); return Empty;
else
return it->second.Data;
}
void DynamicObject::ClearAttribute(const String& name) return it->second.Data;
{
SetAttribute(name, Value());
} }
bool DynamicObject::HasAttribute(const String& name) const bool DynamicObject::HasAttribute(const String& name) const
@ -246,42 +246,42 @@ DynamicObject::AttributeConstIterator DynamicObject::AttributeEnd(void) const
String DynamicObject::GetType(void) const String DynamicObject::GetType(void) const
{ {
String type; return Get("__type");
GetAttribute("__type", &type);
return type;
} }
String DynamicObject::GetName(void) const String DynamicObject::GetName(void) const
{ {
String name; return Get("__name");
GetAttribute("__name", &name);
return name;
} }
bool DynamicObject::IsLocal(void) const bool DynamicObject::IsLocal(void) const
{ {
long local = 0; Value value = Get("__local");
GetAttribute("__local", &local);
return (local != 0); if (value.IsEmpty())
return false;
return (value != 0);
} }
bool DynamicObject::IsAbstract(void) const bool DynamicObject::IsAbstract(void) const
{ {
long abstract = 0; Value value = Get("__abstract");
GetAttribute("__abstract", &abstract);
return (abstract != 0); if (value.IsEmpty())
return false;
return (value != 0);
} }
void DynamicObject::SetSource(const String& value) void DynamicObject::SetSource(const String& value)
{ {
SetAttribute("__source", value); Set("__source", value);
} }
String DynamicObject::GetSource(void) const String DynamicObject::GetSource(void) const
{ {
String source; return Get("__source");
GetAttribute("__source", &source);
return source;
} }
void DynamicObject::Register(void) void DynamicObject::Register(void)
@ -351,8 +351,13 @@ pair<DynamicObject::NameMap::iterator, DynamicObject::NameMap::iterator> Dynamic
ScriptTask::Ptr DynamicObject::InvokeMethod(const String& method, ScriptTask::Ptr DynamicObject::InvokeMethod(const String& method,
const vector<Value>& arguments, ScriptTask::CompletionCallback callback) const vector<Value>& arguments, ScriptTask::CompletionCallback callback)
{ {
Dictionary::Ptr methods; Value value = Get("methods");
if (!GetAttribute("methods", &methods) || !methods->Contains(method))
if (!value.IsObjectType<Dictionary>())
return ScriptTask::Ptr();
Dictionary::Ptr methods = value;
if (!methods->Contains(method))
return ScriptTask::Ptr(); return ScriptTask::Ptr();
String funcName = methods->Get(method); String funcName = methods->Get(method);

View File

@ -76,21 +76,8 @@ public:
void RegisterAttribute(const String& name, DynamicAttributeType type); void RegisterAttribute(const String& name, DynamicAttributeType type);
void SetAttribute(const String& name, const Value& data); void Set(const String& name, const Value& data);
Value Get(const String& name) const;
template<typename T>
bool GetAttribute(const String& name, T *retval) const
{
Value data = InternalGetAttribute(name);
if (data.IsEmpty())
return false;
*retval = static_cast<T>(data);
return true;
}
void ClearAttribute(const String& name);
bool HasAttribute(const String& name) const; bool HasAttribute(const String& name) const;

View File

@ -45,7 +45,17 @@ void Event::ProcessEvents(const system_time& wait_until)
} }
BOOST_FOREACH(const Event& ev, events) { BOOST_FOREACH(const Event& ev, events) {
double st = Utility::GetTime();
ev.m_Callback(); ev.m_Callback();
double et = Utility::GetTime();
if (et - st > 1.0) {
stringstream msgbuf;
msgbuf << "Event call took " << et - st << " seconds.";
Logger::Write(LogWarning, "base", msgbuf.str());
}
} }
} }

View File

@ -39,8 +39,8 @@ Logger::Logger(const Dictionary::Ptr& properties)
if (!IsLocal()) if (!IsLocal())
throw_exception(runtime_error("Logger objects must be local.")); throw_exception(runtime_error("Logger objects must be local."));
String type; String type = Get("type");
if (!GetAttribute("type", &type)) if (type.IsEmpty())
throw_exception(runtime_error("Logger objects must have a 'type' property.")); throw_exception(runtime_error("Logger objects must have a 'type' property."));
ILogger::Ptr impl; ILogger::Ptr impl;
@ -52,8 +52,8 @@ Logger::Logger(const Dictionary::Ptr& properties)
throw_exception(invalid_argument("Syslog is not supported on Windows.")); throw_exception(invalid_argument("Syslog is not supported on Windows."));
#endif /* _WIN32 */ #endif /* _WIN32 */
} else if (type == "file") { } else if (type == "file") {
String path; String path = Get("path");
if (!GetAttribute("path", &path)) if (path.IsEmpty())
throw_exception(invalid_argument("'log' object of type 'file' must have a 'path' property")); throw_exception(invalid_argument("'log' object of type 'file' must have a 'path' property"));
StreamLogger::Ptr slogger = boost::make_shared<StreamLogger>(); StreamLogger::Ptr slogger = boost::make_shared<StreamLogger>();
@ -96,9 +96,11 @@ void Logger::Write(LogSeverity severity, const String& facility,
*/ */
LogSeverity Logger::GetMinSeverity(void) const LogSeverity Logger::GetMinSeverity(void) const
{ {
String strSeverity = "information"; String severity = Get("severity");
GetAttribute("severity", &strSeverity); if (severity.IsEmpty())
return Logger::StringToSeverity(strSeverity); return LogInformation;
else
return Logger::StringToSeverity(severity);
} }
/** /**

View File

@ -21,19 +21,33 @@
using namespace icinga; using namespace icinga;
mutex Object::m_Mutex;
vector<Object::Ptr> Object::m_HeldObjects; vector<Object::Ptr> Object::m_HeldObjects;
#ifdef _DEBUG
set<Object *> Object::m_AliveObjects;
#endif /* _DEBUG */
/** /**
* Default constructor for the Object class. * Default constructor for the Object class.
*/ */
Object::Object(void) Object::Object(void)
{ } {
#ifdef _DEBUG
mutex::scoped_lock lock(m_Mutex);
m_AliveObjects.insert(this);
#endif /* _DEBUG */
}
/** /**
* Destructor for the Object class. * Destructor for the Object class.
*/ */
Object::~Object(void) Object::~Object(void)
{ } {
#ifdef _DEBUG
mutex::scoped_lock lock(m_Mutex);
m_AliveObjects.erase(this);
#endif /* _DEBUG */
}
/** /**
* Temporarily holds onto a reference for an object. This can * Temporarily holds onto a reference for an object. This can
@ -42,6 +56,7 @@ Object::~Object(void)
*/ */
void Object::Hold(void) void Object::Hold(void)
{ {
mutex::scoped_lock lock(m_Mutex);
m_HeldObjects.push_back(GetSelf()); m_HeldObjects.push_back(GetSelf());
} }
@ -50,6 +65,7 @@ void Object::Hold(void)
*/ */
void Object::ClearHeldObjects(void) void Object::ClearHeldObjects(void)
{ {
mutex::scoped_lock lock(m_Mutex);
m_HeldObjects.clear(); m_HeldObjects.clear();
} }
@ -57,3 +73,43 @@ Object::SharedPtrHolder Object::GetSelf(void)
{ {
return Object::SharedPtrHolder(shared_from_this()); return Object::SharedPtrHolder(shared_from_this());
} }
#ifdef _DEBUG
int Object::GetAliveObjects(void)
{
mutex::scoped_lock lock(m_Mutex);
return m_AliveObjects.size();
}
void Object::PrintMemoryProfile(void)
{
map<String, int> types;
ofstream dictfp("dictionaries.dump.tmp");
{
mutex::scoped_lock lock(m_Mutex);
set<Object *>::iterator it;
BOOST_FOREACH(Object *obj, m_AliveObjects) {
pair<map<String, int>::iterator, bool> tt;
tt = types.insert(make_pair(Utility::GetTypeName(typeid(*obj)), 1));
if (!tt.second)
tt.first->second++;
if (typeid(*obj) == typeid(Dictionary)) {
Dictionary::Ptr dict = obj->GetSelf();
dictfp << Value(dict).Serialize() << std::endl;
}
}
}
dictfp.close();
rename("dictionaries.dump.tmp", "dictionaries.dump");
String type;
int count;
BOOST_FOREACH(tie(type, count), types) {
std::cerr << type << ": " << count << std::endl;
}
}
#endif /* _DEBUG */

View File

@ -75,6 +75,11 @@ public:
SharedPtrHolder GetSelf(void); SharedPtrHolder GetSelf(void);
#ifdef _DEBUG
static int GetAliveObjects(void);
static void PrintMemoryProfile(void);
#endif /* _DEBUG */
protected: protected:
Object(void); Object(void);
virtual ~Object(void); virtual ~Object(void);
@ -83,7 +88,11 @@ private:
Object(const Object& other); Object(const Object& other);
Object operator=(const Object& rhs); Object operator=(const Object& rhs);
static mutex m_Mutex;
static vector<Object::Ptr> m_HeldObjects; static vector<Object::Ptr> m_HeldObjects;
#ifdef _DEBUG
static set<Object *> m_AliveObjects;
#endif /* _DEBUG */
}; };
/** /**

View File

@ -5,6 +5,7 @@ using namespace icinga;
const size_t String::NPos = std::string::npos; const size_t String::NPos = std::string::npos;
String::String(void) String::String(void)
: m_Data()
{ } { }
String::String(const char *data) String::String(const char *data)
@ -183,6 +184,21 @@ bool icinga::operator==(const char *lhs, const String& rhs)
return lhs == static_cast<std::string>(rhs); return lhs == static_cast<std::string>(rhs);
} }
bool icinga::operator!=(const String& lhs, const String& rhs)
{
return static_cast<std::string>(lhs) != static_cast<std::string>(rhs);
}
bool icinga::operator!=(const String& lhs, const char *rhs)
{
return static_cast<std::string>(lhs) != rhs;
}
bool icinga::operator!=(const char *lhs, const String& rhs)
{
return lhs != static_cast<std::string>(rhs);
}
String::Iterator icinga::range_begin(String& x) String::Iterator icinga::range_begin(String& x)
{ {
return x.Begin(); return x.Begin();

View File

@ -85,6 +85,10 @@ I2_BASE_API bool operator==(const String& lhs, const String& rhs);
I2_BASE_API bool operator==(const String& lhs, const char *rhs); I2_BASE_API bool operator==(const String& lhs, const char *rhs);
I2_BASE_API bool operator==(const char *lhs, const String& rhs); I2_BASE_API bool operator==(const char *lhs, const String& rhs);
I2_BASE_API bool operator!=(const String& lhs, const String& rhs);
I2_BASE_API bool operator!=(const String& lhs, const char *rhs);
I2_BASE_API bool operator!=(const char *lhs, const String& rhs);
I2_BASE_API String::Iterator range_begin(String& x); I2_BASE_API String::Iterator range_begin(String& x);
I2_BASE_API String::ConstIterator range_begin(const String& x); I2_BASE_API String::ConstIterator range_begin(const String& x);
I2_BASE_API String::Iterator range_end(String& x); I2_BASE_API String::Iterator range_end(String& x);

View File

@ -96,7 +96,7 @@ void Timer::Call(void)
double et = Utility::GetTime(); double et = Utility::GetTime();
if (et - st > 3) { if (et - st > 1.0) {
stringstream msgbuf; stringstream msgbuf;
msgbuf << "Timer call took " << et - st << " seconds."; msgbuf << "Timer call took " << et - st << " seconds.";
Logger::Write(LogWarning, "base", msgbuf.str()); Logger::Write(LogWarning, "base", msgbuf.str());

View File

@ -22,6 +22,8 @@
using namespace icinga; using namespace icinga;
Value Empty;
/** /**
* Checks whether the variant is empty. * Checks whether the variant is empty.
* *

View File

@ -131,6 +131,8 @@ private:
mutable boost::variant<boost::blank, double, String, Object::Ptr> m_Value; mutable boost::variant<boost::blank, double, String, Object::Ptr> m_Value;
}; };
static Value Empty;
} }
#endif /* VALUE_H */ #endif /* VALUE_H */

View File

@ -32,8 +32,8 @@ Host::Host(const Dictionary::Ptr& properties)
String Host::GetAlias(void) const String Host::GetAlias(void) const
{ {
String value; String value = Get("alias");
if (GetAttribute("alias", &value)) if (!value.IsEmpty())
return value; return value;
else else
return GetName(); return GetName();
@ -56,17 +56,14 @@ Host::Ptr Host::GetByName(const String& name)
Dictionary::Ptr Host::GetGroups(void) const Dictionary::Ptr Host::GetGroups(void) const
{ {
Dictionary::Ptr value; return Get("hostgroups");
GetAttribute("hostgroups", &value);
return value;
} }
set<String> Host::GetParents(void) set<String> Host::GetParents(void)
{ {
set<String> parents; set<String> parents;
Dictionary::Ptr dependencies; Dictionary::Ptr dependencies = Get("dependencies");
GetAttribute("dependencies", &dependencies);
if (dependencies) { if (dependencies) {
dependencies = Service::ResolveDependencies(GetSelf(), dependencies); dependencies = Service::ResolveDependencies(GetSelf(), dependencies);
@ -89,15 +86,12 @@ set<String> Host::GetParents(void)
Dictionary::Ptr Host::GetMacros(void) const Dictionary::Ptr Host::GetMacros(void) const
{ {
Dictionary::Ptr value; return Get("macros");
GetAttribute("macros", &value);
return value;
} }
bool Host::IsReachable(void) bool Host::IsReachable(void)
{ {
Dictionary::Ptr dependencies; Dictionary::Ptr dependencies = Get("dependencies");
GetAttribute("dependencies", &dependencies);
if (dependencies) { if (dependencies) {
dependencies = Service::ResolveDependencies(GetSelf(), dependencies); dependencies = Service::ResolveDependencies(GetSelf(), dependencies);
@ -117,8 +111,7 @@ bool Host::IsReachable(void)
bool Host::IsUp(void) bool Host::IsUp(void)
{ {
Dictionary::Ptr hostchecks; Dictionary::Ptr hostchecks = Get("hostchecks");
GetAttribute("hostchecks", &hostchecks);
if (hostchecks) { if (hostchecks) {
hostchecks = Service::ResolveDependencies(GetSelf(), hostchecks); hostchecks = Service::ResolveDependencies(GetSelf(), hostchecks);

View File

@ -25,8 +25,7 @@ REGISTER_CLASS(HostGroup);
String HostGroup::GetAlias(void) const String HostGroup::GetAlias(void) const
{ {
String value; String value = Get("alias");
GetAttribute("alias", &value);
if (!value.IsEmpty()) if (!value.IsEmpty())
return value; return value;
@ -36,16 +35,12 @@ String HostGroup::GetAlias(void) const
String HostGroup::GetNotesUrl(void) const String HostGroup::GetNotesUrl(void) const
{ {
String value; return Get("notes_url");
GetAttribute("notes_url", &value);
return value;
} }
String HostGroup::GetActionUrl(void) const String HostGroup::GetActionUrl(void) const
{ {
String value; return Get("action_url");
GetAttribute("action_url", &value);
return value;
} }
bool HostGroup::Exists(const String& name) bool HostGroup::Exists(const String& name)

View File

@ -52,9 +52,9 @@ Service::Service(const Dictionary::Ptr& serializedObject)
String Service::GetAlias(void) const String Service::GetAlias(void) const
{ {
String value; String value = Get("alias");
if (GetAttribute("alias", &value)) if (!value.IsEmpty())
return value; return value;
return GetName(); return GetName();
@ -77,8 +77,9 @@ Service::Ptr Service::GetByName(const String& name)
Host::Ptr Service::GetHost(void) const Host::Ptr Service::GetHost(void) const
{ {
String hostname; String hostname = Get("host_name");
if (!GetAttribute("host_name", &hostname))
if (hostname.IsEmpty())
throw_exception(runtime_error("Service object is missing the 'host_name' property.")); throw_exception(runtime_error("Service object is missing the 'host_name' property."));
return Host::GetByName(hostname); return Host::GetByName(hostname);
@ -86,29 +87,30 @@ Host::Ptr Service::GetHost(void) const
Dictionary::Ptr Service::GetMacros(void) const Dictionary::Ptr Service::GetMacros(void) const
{ {
Dictionary::Ptr macros; return Get("macros");
GetAttribute("macros", &macros);
return macros;
} }
String Service::GetCheckCommand(void) const String Service::GetCheckCommand(void) const
{ {
String value; return Get("check_command");
GetAttribute("check_command", &value);
return value;
} }
long Service::GetMaxCheckAttempts(void) const long Service::GetMaxCheckAttempts(void) const
{ {
long value = 3; Value value = Get("max_check_attempts");
GetAttribute("max_check_attempts", &value);
if (value.IsEmpty())
return 3;
return value; return value;
} }
long Service::GetCheckInterval(void) const long Service::GetCheckInterval(void) const
{ {
long value = 300; Value value = Get("check_interval");
GetAttribute("check_interval", &value);
if (value.IsEmpty())
return 300;
if (value < 15) if (value < 15)
value = 15; value = 15;
@ -118,18 +120,17 @@ long Service::GetCheckInterval(void) const
long Service::GetRetryInterval(void) const long Service::GetRetryInterval(void) const
{ {
long value; Value value = Get("retry_interval");
if (!GetAttribute("retry_interval", &value))
value = GetCheckInterval() / 5; if (value.IsEmpty())
return GetCheckInterval() / 5;
return value; return value;
} }
Dictionary::Ptr Service::GetDependencies(void) const Dictionary::Ptr Service::GetDependencies(void) const
{ {
Dictionary::Ptr value; return Get("dependencies");
GetAttribute("dependencies", &value);
return value;
} }
void Service::GetDependenciesRecursive(const Dictionary::Ptr& result) const { void Service::GetDependenciesRecursive(const Dictionary::Ptr& result) const {
@ -154,16 +155,12 @@ void Service::GetDependenciesRecursive(const Dictionary::Ptr& result) const {
Dictionary::Ptr Service::GetGroups(void) const Dictionary::Ptr Service::GetGroups(void) const
{ {
Dictionary::Ptr value; return Get("servicegroups");
GetAttribute("servicegroups", &value);
return value;
} }
Dictionary::Ptr Service::GetCheckers(void) const Dictionary::Ptr Service::GetCheckers(void) const
{ {
Dictionary::Ptr value; return Get("checkers");
GetAttribute("checkers", &value);
return value;
} }
bool Service::IsReachable(void) const bool Service::IsReachable(void) const
@ -200,33 +197,39 @@ bool Service::IsReachable(void) const
void Service::SetSchedulingOffset(long offset) void Service::SetSchedulingOffset(long offset)
{ {
SetAttribute("scheduling_offset", offset); Set("scheduling_offset", offset);
} }
long Service::GetSchedulingOffset(void) long Service::GetSchedulingOffset(void)
{ {
long value; Value value = Get("scheduling_offset");
if (!GetAttribute("scheduling_offset", &value)) {
if (value.IsEmpty()) {
value = rand(); value = rand();
SetSchedulingOffset(value); SetSchedulingOffset(value);
} }
return value; return value;
} }
void Service::SetNextCheck(double nextCheck) void Service::SetNextCheck(double nextCheck)
{ {
SetAttribute("next_check", nextCheck); Set("next_check", nextCheck);
} }
double Service::GetNextCheck(void) double Service::GetNextCheck(void)
{ {
double value; Value value = Get("next_check");
if (!GetAttribute("next_check", &value)) {
if (value.IsEmpty()) {
UpdateNextCheck(); UpdateNextCheck();
if (!GetAttribute("next_check", &value)) value = Get("next_check");
if (value.IsEmpty())
throw_exception(runtime_error("Failed to schedule next check.")); throw_exception(runtime_error("Failed to schedule next check."));
} }
return value; return value;
} }
@ -246,87 +249,98 @@ void Service::UpdateNextCheck(void)
void Service::SetChecker(const String& checker) void Service::SetChecker(const String& checker)
{ {
SetAttribute("checker", checker); Set("checker", checker);
} }
String Service::GetChecker(void) const String Service::GetChecker(void) const
{ {
String value; return Get("checker");
GetAttribute("checker", &value);
return value;
} }
void Service::SetCurrentCheckAttempt(long attempt) void Service::SetCurrentCheckAttempt(long attempt)
{ {
SetAttribute("check_attempt", attempt); Set("check_attempt", attempt);
} }
long Service::GetCurrentCheckAttempt(void) const long Service::GetCurrentCheckAttempt(void) const
{ {
long value = 1; Value value = Get("check_attempt");
GetAttribute("check_attempt", &value);
if (value.IsEmpty())
return 1;
return value; return value;
} }
void Service::SetState(ServiceState state) void Service::SetState(ServiceState state)
{ {
SetAttribute("state", static_cast<long>(state)); Set("state", static_cast<long>(state));
} }
ServiceState Service::GetState(void) const ServiceState Service::GetState(void) const
{ {
long value = StateUnknown; Value value = Get("state");
GetAttribute("state", &value);
return static_cast<ServiceState>(value); if (value.IsEmpty())
return StateUnknown;
int ivalue = static_cast<int>(value);
return static_cast<ServiceState>(ivalue);
} }
void Service::SetStateType(ServiceStateType type) void Service::SetStateType(ServiceStateType type)
{ {
SetAttribute("state_type", static_cast<long>(type)); Set("state_type", static_cast<long>(type));
} }
ServiceStateType Service::GetStateType(void) const ServiceStateType Service::GetStateType(void) const
{ {
long value = StateTypeHard; Value value = Get("state_type");
GetAttribute("state_type", &value);
return static_cast<ServiceStateType>(value); if (value.IsEmpty())
return StateTypeHard;
int ivalue = static_cast<int>(value);
return static_cast<ServiceStateType>(ivalue);
} }
void Service::SetLastCheckResult(const Dictionary::Ptr& result) void Service::SetLastCheckResult(const Dictionary::Ptr& result)
{ {
SetAttribute("last_result", result); Set("last_result", result);
} }
Dictionary::Ptr Service::GetLastCheckResult(void) const Dictionary::Ptr Service::GetLastCheckResult(void) const
{ {
Dictionary::Ptr value; return Get("last_result");
GetAttribute("last_result", &value);
return value;
} }
void Service::SetLastStateChange(double ts) void Service::SetLastStateChange(double ts)
{ {
SetAttribute("last_state_change", static_cast<long>(ts)); Set("last_state_change", static_cast<long>(ts));
} }
double Service::GetLastStateChange(void) const double Service::GetLastStateChange(void) const
{ {
long value; Value value = Get("last_state_change");
if (!GetAttribute("last_state_change", &value))
value = IcingaApplication::GetInstance()->GetStartTime(); if (value.IsEmpty())
return IcingaApplication::GetInstance()->GetStartTime();
return value; return value;
} }
void Service::SetLastHardStateChange(double ts) void Service::SetLastHardStateChange(double ts)
{ {
SetAttribute("last_hard_state_change", ts); Set("last_hard_state_change", ts);
} }
double Service::GetLastHardStateChange(void) const double Service::GetLastHardStateChange(void) const
{ {
double value; Value value = Get("last_hard_state_change");
if (!GetAttribute("last_hard_state_change", &value))
if (value.IsEmpty())
value = IcingaApplication::GetInstance()->GetStartTime(); value = IcingaApplication::GetInstance()->GetStartTime();
return value; return value;
} }
@ -442,8 +456,7 @@ bool Service::IsAllowedChecker(const String& checker) const
Dictionary::Ptr Service::ResolveDependencies(const Host::Ptr& host, const Dictionary::Ptr& dependencies) Dictionary::Ptr Service::ResolveDependencies(const Host::Ptr& host, const Dictionary::Ptr& dependencies)
{ {
Dictionary::Ptr services; Dictionary::Ptr services = host->Get("services");
host->GetAttribute("services", &services);
Dictionary::Ptr result = boost::make_shared<Dictionary>(); Dictionary::Ptr result = boost::make_shared<Dictionary>();

View File

@ -25,8 +25,7 @@ REGISTER_CLASS(ServiceGroup);
String ServiceGroup::GetAlias(void) const String ServiceGroup::GetAlias(void) const
{ {
String value; String value = Get("alias");
GetAttribute("alias", &value);
if (!value.IsEmpty()) if (!value.IsEmpty())
return value; return value;
@ -36,16 +35,12 @@ String ServiceGroup::GetAlias(void) const
String ServiceGroup::GetNotesUrl(void) const String ServiceGroup::GetNotesUrl(void) const
{ {
String value; return Get("notes_url");
GetAttribute("notes_url", &value);
return value;
} }
String ServiceGroup::GetActionUrl(void) const String ServiceGroup::GetActionUrl(void) const
{ {
String value; return Get("action_url");
GetAttribute("action_url", &value);
return value;
} }
bool ServiceGroup::Exists(const String& name) bool ServiceGroup::Exists(const String& name)

View File

@ -78,7 +78,7 @@ void CheckerComponent::CheckTimerHandler(void)
task = service->InvokeMethod("check", arguments, boost::bind(&CheckerComponent::CheckCompletedHandler, this, service, _1)); task = service->InvokeMethod("check", arguments, boost::bind(&CheckerComponent::CheckCompletedHandler, this, service, _1));
assert(task); /* TODO: gracefully handle missing methods */ assert(task); /* TODO: gracefully handle missing methods */
service->SetAttribute("current_task", task); service->Set("current_task", task);
tasks++; tasks++;
} }
@ -92,7 +92,7 @@ void CheckerComponent::CheckTimerHandler(void)
void CheckerComponent::CheckCompletedHandler(const Service::Ptr& service, const ScriptTask::Ptr& task) void CheckerComponent::CheckCompletedHandler(const Service::Ptr& service, const ScriptTask::Ptr& task)
{ {
service->ClearAttribute("current_task"); service->Set("current_task", Empty);
try { try {
Value vresult = task->GetResult(); Value vresult = task->GetResult();

View File

@ -174,6 +174,9 @@ void CIBSyncComponent::LocalObjectUnregisteredHandler(const DynamicObject::Ptr&
void CIBSyncComponent::TransactionClosingHandler(const set<DynamicObject::Ptr>& modifiedObjects) void CIBSyncComponent::TransactionClosingHandler(const set<DynamicObject::Ptr>& modifiedObjects)
{ {
if (modifiedObjects.empty())
return;
stringstream msgbuf; stringstream msgbuf;
msgbuf << "Sending " << modifiedObjects.size() << " replication updates."; msgbuf << "Sending " << modifiedObjects.size() << " replication updates.";
Logger::Write(LogInformation, "cibsync", msgbuf.str()); Logger::Write(LogInformation, "cibsync", msgbuf.str());
@ -183,7 +186,6 @@ void CIBSyncComponent::TransactionClosingHandler(const set<DynamicObject::Ptr>&
continue; continue;
RequestMessage request = MakeObjectMessage(object, "config::ObjectUpdate", DynamicObject::GetCurrentTx(), true); RequestMessage request = MakeObjectMessage(object, "config::ObjectUpdate", DynamicObject::GetCurrentTx(), true);
EndpointManager::GetInstance()->SendMulticastMessage(m_Endpoint, request); EndpointManager::GetInstance()->SendMulticastMessage(m_Endpoint, request);
} }
} }

View File

@ -30,38 +30,40 @@ void ConvenienceComponent::Start(void)
ConfigItem::OnRemoved.connect(boost::bind(&ConvenienceComponent::HostRemovedHandler, this, _1)); ConfigItem::OnRemoved.connect(boost::bind(&ConvenienceComponent::HostRemovedHandler, this, _1));
} }
void ConvenienceComponent::CopyServiceAttributes(const Host::Ptr& host, const Dictionary::Ptr& serviceDesc, const ConfigItemBuilder::Ptr& builder) template<typename TDict>
static void CopyServiceAttributes(const Host::Ptr& host, TDict serviceDesc,
const ConfigItemBuilder::Ptr& builder)
{ {
/* TODO: we only need to copy macros if this is an inline definition, /* TODO: we only need to copy macros if this is an inline definition,
* i.e. host->GetProperties() != service, however for now we just * i.e. host->GetProperties() != service, however for now we just
* copy them anyway. */ * copy them anyway. */
Dictionary::Ptr macros; Value macros = serviceDesc->Get("macros");
if (serviceDesc->Get("macros", &macros)) if (!macros.IsEmpty())
builder->AddExpression("macros", OperatorPlus, macros); builder->AddExpression("macros", OperatorPlus, macros);
long checkInterval; Value checkInterval = serviceDesc->Get("check_interval");
if (serviceDesc->Get("check_interval", &checkInterval)) if (!checkInterval.IsEmpty())
builder->AddExpression("check_interval", OperatorSet, checkInterval); builder->AddExpression("check_interval", OperatorSet, checkInterval);
long retryInterval; Value retryInterval = serviceDesc->Get("retry_interval");
if (serviceDesc->Get("retry_interval", &retryInterval)) if (!retryInterval.IsEmpty())
builder->AddExpression("retry_interval", OperatorSet, retryInterval); builder->AddExpression("retry_interval", OperatorSet, retryInterval);
Dictionary::Ptr sgroups; Value sgroups = serviceDesc->Get("servicegroups");
if (serviceDesc->Get("servicegroups", &sgroups)) if (!sgroups.IsEmpty())
builder->AddExpression("servicegroups", OperatorPlus, sgroups); builder->AddExpression("servicegroups", OperatorPlus, sgroups);
Dictionary::Ptr checkers; Value checkers = serviceDesc->Get("checkers");
if (serviceDesc->Get("checkers", &checkers)) if (!checkers.IsEmpty())
builder->AddExpression("checkers", OperatorSet, checkers); builder->AddExpression("checkers", OperatorSet, checkers);
Dictionary::Ptr dependencies; Value dependencies = serviceDesc->Get("dependencies");
if (serviceDesc->Get("dependencies", &dependencies)) if (!dependencies.IsEmpty())
builder->AddExpression("dependencies", OperatorPlus, builder->AddExpression("dependencies", OperatorPlus,
Service::ResolveDependencies(host, dependencies)); Service::ResolveDependencies(host, dependencies));
Dictionary::Ptr hostchecks; Value hostchecks = serviceDesc->Get("hostchecks");
if (serviceDesc->Get("hostchecks", &hostchecks)) if (!hostchecks.IsEmpty())
builder->AddExpression("dependencies", OperatorPlus, builder->AddExpression("dependencies", OperatorPlus,
Service::ResolveDependencies(host, hostchecks)); Service::ResolveDependencies(host, hostchecks));
} }
@ -77,14 +79,12 @@ void ConvenienceComponent::HostCommittedHandler(const ConfigItem::Ptr& item)
if (!host) if (!host)
return; return;
Dictionary::Ptr oldServices; Dictionary::Ptr oldServices = host->Get("convenience_services");
host->GetAttribute("convenience_services", &oldServices);
Dictionary::Ptr newServices; Dictionary::Ptr newServices;
newServices = boost::make_shared<Dictionary>(); newServices = boost::make_shared<Dictionary>();
Dictionary::Ptr serviceDescs; Dictionary::Ptr serviceDescs = host->Get("services");
host->GetAttribute("services", &serviceDescs);
if (serviceDescs) { if (serviceDescs) {
String svcname; String svcname;
@ -100,15 +100,15 @@ void ConvenienceComponent::HostCommittedHandler(const ConfigItem::Ptr& item)
builder->AddExpression("host_name", OperatorSet, item->GetName()); builder->AddExpression("host_name", OperatorSet, item->GetName());
builder->AddExpression("alias", OperatorSet, svcname); builder->AddExpression("alias", OperatorSet, svcname);
CopyServiceAttributes(host, host->GetProperties(), builder); CopyServiceAttributes(host, host, builder);
if (svcdesc.IsScalar()) { if (svcdesc.IsScalar()) {
builder->AddParent(svcdesc); builder->AddParent(svcdesc);
} else if (svcdesc.IsObjectType<Dictionary>()) { } else if (svcdesc.IsObjectType<Dictionary>()) {
Dictionary::Ptr service = svcdesc; Dictionary::Ptr service = svcdesc;
String parent; String parent = service->Get("service");
if (!service->Get("service", &parent)) if (parent.IsEmpty())
parent = svcname; parent = svcname;
builder->AddParent(parent); builder->AddParent(parent);
@ -136,7 +136,7 @@ void ConvenienceComponent::HostCommittedHandler(const ConfigItem::Ptr& item)
} }
} }
host->SetAttribute("convenience_services", newServices); host->Set("convenience_services", newServices);
} }
void ConvenienceComponent::HostRemovedHandler(const ConfigItem::Ptr& item) void ConvenienceComponent::HostRemovedHandler(const ConfigItem::Ptr& item)
@ -149,8 +149,7 @@ void ConvenienceComponent::HostRemovedHandler(const ConfigItem::Ptr& item)
if (!host) if (!host)
return; return;
Dictionary::Ptr services; Dictionary::Ptr services = host->Get("convenience_services");
host->GetAttribute("convenience_services", &services);
if (!services) if (!services)
return; return;

View File

@ -32,7 +32,6 @@ public:
virtual void Start(void); virtual void Start(void);
private: private:
void CopyServiceAttributes(const Host::Ptr& host, const Dictionary::Ptr& serviceDesc, const ConfigItemBuilder::Ptr& builder);
void HostAddedHandler(const ConfigItem::Ptr& item); void HostAddedHandler(const ConfigItem::Ptr& item);
void HostCommittedHandler(const ConfigItem::Ptr& item); void HostCommittedHandler(const ConfigItem::Ptr& item);
void HostRemovedHandler(const ConfigItem::Ptr& item); void HostRemovedHandler(const ConfigItem::Ptr& item);

View File

@ -316,8 +316,8 @@ bool DiscoveryComponent::HasMessagePermission(const Dictionary::Ptr& roles, cons
Value roleName; Value roleName;
BOOST_FOREACH(tie(tuples::ignore, roleName), roles) { BOOST_FOREACH(tie(tuples::ignore, roleName), roles) {
DynamicObject::Ptr role = DynamicObject::GetObject("Role", roleName); DynamicObject::Ptr role = DynamicObject::GetObject("Role", roleName);
Dictionary::Ptr permissions; Dictionary::Ptr permissions = role->Get(messageType);
if (!role->GetAttribute(messageType, &permissions)) if (!permissions)
continue; continue;
Value permission; Value permission;
@ -359,7 +359,7 @@ void DiscoveryComponent::ProcessDiscoveryMessage(const String& identity, const D
DynamicObject::Ptr endpointConfig = DynamicObject::GetObject("Endpoint", identity); DynamicObject::Ptr endpointConfig = DynamicObject::GetObject("Endpoint", identity);
Dictionary::Ptr roles; Dictionary::Ptr roles;
if (endpointConfig) if (endpointConfig)
endpointConfig->GetAttribute("roles", &roles); roles = endpointConfig->Get("roles");
Endpoint::Ptr endpoint = EndpointManager::GetInstance()->GetEndpointByIdentity(identity); Endpoint::Ptr endpoint = EndpointManager::GetInstance()->GetEndpointByIdentity(identity);
@ -449,8 +449,9 @@ void DiscoveryComponent::DiscoveryTimerHandler(void)
if (endpointManager->GetEndpointByIdentity(object->GetName())) if (endpointManager->GetEndpointByIdentity(object->GetName()))
continue; continue;
String node, service; String node = object->Get("node");
if (object->GetAttribute("node", &node) && object->GetAttribute("service", &service)) { String service = object->Get("service");
if (!node.IsEmpty() && !service.IsEmpty()) {
/* reconnect to this endpoint */ /* reconnect to this endpoint */
endpointManager->AddConnection(node, service); endpointManager->AddConnection(node, service);
} }

View File

@ -9,6 +9,7 @@ icinga_SOURCES = \
icinga_CPPFLAGS = \ icinga_CPPFLAGS = \
-DI2_ICINGALAUNCHER_BUILD \ -DI2_ICINGALAUNCHER_BUILD \
$(LTDLINCL) \
$(BOOST_CPPFLAGS) \ $(BOOST_CPPFLAGS) \
-I${top_srcdir}/base \ -I${top_srcdir}/base \
-I${top_srcdir}/dyn \ -I${top_srcdir}/dyn \
@ -20,6 +21,7 @@ icinga_LDFLAGS = \
$(BOOST_LDFLAGS) $(BOOST_LDFLAGS)
icinga_LDADD = \ icinga_LDADD = \
$(LIBLTDL) \
$(BOOST_SIGNALS_LIB) \ $(BOOST_SIGNALS_LIB) \
$(BOOST_THREAD_LIB) \ $(BOOST_THREAD_LIB) \
${top_builddir}/base/libbase.la \ ${top_builddir}/base/libbase.la \

View File

@ -31,7 +31,6 @@ using namespace icinga;
const String IcingaApplication::DefaultPidPath = "icinga.pid"; const String IcingaApplication::DefaultPidPath = "icinga.pid";
IcingaApplication::IcingaApplication(void) IcingaApplication::IcingaApplication(void)
: m_PidPath(DefaultPidPath)
{ } { }
/** /**
@ -49,13 +48,14 @@ int IcingaApplication::Main(const vector<String>& args)
consoleLogConfig->SetLocal(true); consoleLogConfig->SetLocal(true);
consoleLogConfig->AddExpression("type", OperatorSet, "console"); consoleLogConfig->AddExpression("type", OperatorSet, "console");
consoleLogConfig->Compile()->Commit(); consoleLogConfig->Compile()->Commit();
consoleLogConfig.reset();
/* restore the previous program state */ /* restore the previous program state */
DynamicObject::RestoreObjects("retention.dat"); DynamicObject::RestoreObjects("retention.dat");
/* periodically dump the program state */ /* periodically dump the program state */
m_RetentionTimer = boost::make_shared<Timer>(); m_RetentionTimer = boost::make_shared<Timer>();
m_RetentionTimer->SetInterval(10); m_RetentionTimer->SetInterval(60);
m_RetentionTimer->OnTimerExpired.connect(boost::bind(&IcingaApplication::DumpProgramState, this)); m_RetentionTimer->OnTimerExpired.connect(boost::bind(&IcingaApplication::DumpProgramState, this));
m_RetentionTimer->Start(); m_RetentionTimer->Start();
@ -119,13 +119,15 @@ int IcingaApplication::Main(const vector<String>& args)
cibsyncComponentConfig->SetName("cibsync"); cibsyncComponentConfig->SetName("cibsync");
cibsyncComponentConfig->SetLocal(true); cibsyncComponentConfig->SetLocal(true);
cibsyncComponentConfig->Compile()->Commit(); cibsyncComponentConfig->Compile()->Commit();
cibsyncComponentConfig.reset();
/* load convenience config component */ /* load convenience config component */
ConfigItemBuilder::Ptr convenienceComponentConfig = boost::make_shared<ConfigItemBuilder>(); ConfigItemBuilder::Ptr convenienceComponentConfig = boost::make_shared<ConfigItemBuilder>();
convenienceComponentConfig->SetType("Component"); convenienceComponentConfig->SetType("Component");
convenienceComponentConfig->SetName("convenience"); convenienceComponentConfig->SetName("convenience");
convenienceComponentConfig->SetLocal(true); convenienceComponentConfig->SetLocal(true);
//convenienceComponentConfig->Compile()->Commit(); convenienceComponentConfig->Compile()->Commit();
convenienceComponentConfig.reset();
/* load config file */ /* load config file */
vector<ConfigItem::Ptr> configItems = ConfigCompiler::CompileFile(configFile); vector<ConfigItem::Ptr> configItems = ConfigCompiler::CompileFile(configFile);
@ -144,15 +146,18 @@ int IcingaApplication::Main(const vector<String>& args)
if (!icingaConfig->IsLocal()) if (!icingaConfig->IsLocal())
throw_exception(runtime_error("'icinga' application object must be 'local'.")); throw_exception(runtime_error("'icinga' application object must be 'local'."));
icingaConfig->GetAttribute("cert", &m_CertificateFile); m_CertificateFile = icingaConfig->Get("cert");
icingaConfig->GetAttribute("ca", &m_CAFile); m_CAFile = icingaConfig->Get("ca");
icingaConfig->GetAttribute("node", &m_Node); m_Node = icingaConfig->Get("node");
icingaConfig->GetAttribute("service", &m_Service); m_Service = icingaConfig->Get("service");
icingaConfig->GetAttribute("pidpath", &m_PidPath); m_PidPath = icingaConfig->Get("pidpath");
icingaConfig->GetAttribute("macros", &m_Macros);
String logpath; if (m_PidPath.IsEmpty())
icingaConfig->GetAttribute("logpath", &logpath); m_PidPath = DefaultPidPath;
m_Macros = icingaConfig->Get("macros");
String logpath = icingaConfig->Get("logpath");
if (!logpath.IsEmpty()) { if (!logpath.IsEmpty()) {
ConfigItemBuilder::Ptr fileLogConfig = boost::make_shared<ConfigItemBuilder>(); ConfigItemBuilder::Ptr fileLogConfig = boost::make_shared<ConfigItemBuilder>();
fileLogConfig->SetType("Logger"); fileLogConfig->SetType("Logger");