mirror of
https://github.com/Icinga/icinga2.git
synced 2025-04-08 17:05:25 +02:00
Make attribute lookups O(1).
This commit is contained in:
parent
8f11e0412d
commit
35c79a76c1
@ -121,7 +121,6 @@ void CheckerComponent::CheckThreadProc(void)
|
||||
}
|
||||
|
||||
service->SetForceNextCheck(false);
|
||||
service->SetFirstCheck(false);
|
||||
|
||||
Logger::Write(LogDebug, "checker", "Executing service check for '" + service->GetName() + "'");
|
||||
|
||||
@ -177,7 +176,7 @@ void CheckerComponent::CheckerChangedHandler(const Service::Ptr& service)
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
|
||||
ObjectLock olock(service); /* also required for the key extractor */
|
||||
String checker = service->GetChecker();
|
||||
String checker = service->GetCurrentChecker();
|
||||
|
||||
if (checker == EndpointManager::GetInstance()->GetIdentity() || checker == m_Endpoint->GetName()) {
|
||||
if (m_PendingServices.find(service) != m_PendingServices.end())
|
||||
|
@ -534,12 +534,14 @@ void CompatComponent::StatusTimerHandler(void)
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Host")) {
|
||||
Host::Ptr host = static_pointer_cast<Host>(object);
|
||||
|
||||
stringstream tempstatusfp, tempobjectfp;
|
||||
|
||||
stringstream tempstatusfp;
|
||||
tempstatusfp << std::fixed;
|
||||
DumpHostStatus(tempstatusfp, host);
|
||||
DumpHostObject(tempobjectfp, host);
|
||||
|
||||
statusfp << tempstatusfp.str();
|
||||
|
||||
stringstream tempobjectfp;
|
||||
tempobjectfp << std::fixed;
|
||||
DumpHostObject(tempobjectfp, host);
|
||||
objectfp << tempobjectfp.str();
|
||||
}
|
||||
|
||||
@ -547,6 +549,7 @@ void CompatComponent::StatusTimerHandler(void)
|
||||
HostGroup::Ptr hg = static_pointer_cast<HostGroup>(object);
|
||||
|
||||
stringstream tempobjectfp;
|
||||
tempobjectfp << std::fixed;
|
||||
|
||||
{
|
||||
ObjectLock olock(hg);
|
||||
@ -568,12 +571,14 @@ void CompatComponent::StatusTimerHandler(void)
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Service")) {
|
||||
Service::Ptr service = static_pointer_cast<Service>(object);
|
||||
|
||||
stringstream tempstatusfp, tempobjectfp;
|
||||
|
||||
DumpServiceStatus(statusfp, service);
|
||||
DumpServiceObject(objectfp, service);
|
||||
|
||||
stringstream tempstatusfp;
|
||||
tempstatusfp << std::fixed;
|
||||
DumpServiceStatus(tempstatusfp, service);
|
||||
statusfp << tempstatusfp.str();
|
||||
|
||||
stringstream tempobjectfp;
|
||||
tempobjectfp << std::fixed;
|
||||
DumpServiceObject(tempobjectfp, service);
|
||||
objectfp << tempobjectfp.str();
|
||||
}
|
||||
|
||||
@ -581,6 +586,7 @@ void CompatComponent::StatusTimerHandler(void)
|
||||
ServiceGroup::Ptr sg = static_pointer_cast<ServiceGroup>(object);
|
||||
|
||||
stringstream tempobjectfp;
|
||||
tempobjectfp << std::fixed;
|
||||
|
||||
{
|
||||
ObjectLock olock(sg);
|
||||
|
@ -102,7 +102,7 @@ void DelegationComponent::DelegationTimerHandler(void)
|
||||
services.push_back(service);
|
||||
|
||||
ObjectLock olock(service);
|
||||
String checker = service->GetChecker();
|
||||
String checker = service->GetCurrentChecker();
|
||||
if (checker.IsEmpty())
|
||||
continue;
|
||||
|
||||
@ -122,7 +122,7 @@ void DelegationComponent::DelegationTimerHandler(void)
|
||||
BOOST_FOREACH(const Service::Ptr& service, services) {
|
||||
ObjectLock olock(service);
|
||||
|
||||
String checker = service->GetChecker();
|
||||
String checker = service->GetCurrentChecker();
|
||||
|
||||
Endpoint::Ptr oldEndpoint;
|
||||
if (Endpoint::Exists(checker))
|
||||
@ -160,7 +160,7 @@ void DelegationComponent::DelegationTimerHandler(void)
|
||||
|
||||
/* clear the service's current checker */
|
||||
if (!checker.IsEmpty()) {
|
||||
service->SetChecker("");
|
||||
service->SetCurrentChecker("");
|
||||
|
||||
if (oldEndpoint)
|
||||
histogram[oldEndpoint]--;
|
||||
@ -173,7 +173,7 @@ void DelegationComponent::DelegationTimerHandler(void)
|
||||
continue;
|
||||
|
||||
ObjectLock clock(candidate);
|
||||
service->SetChecker(candidate->GetName());
|
||||
service->SetCurrentChecker(candidate->GetName());
|
||||
histogram[candidate]++;
|
||||
|
||||
/* reschedule the service; this avoids "check floods"
|
||||
@ -207,7 +207,7 @@ void DelegationComponent::DelegationTimerHandler(void)
|
||||
continue;
|
||||
}
|
||||
|
||||
assert(!service->GetChecker().IsEmpty());
|
||||
assert(!service->GetCurrentChecker().IsEmpty());
|
||||
}
|
||||
|
||||
Endpoint::Ptr endpoint;
|
||||
|
@ -68,7 +68,7 @@ void ReplicationComponent::CheckResultRequestHandler(const RequestMessage& reque
|
||||
if (!cr)
|
||||
return;
|
||||
|
||||
if (cr->Contains("checker") && cr->Get("checker") == EndpointManager::GetInstance()->GetIdentity())
|
||||
if (cr->Contains("current_checker") && cr->Get("current_checker") == EndpointManager::GetInstance()->GetIdentity())
|
||||
return;
|
||||
|
||||
Service::UpdateStatistics(cr);
|
||||
|
@ -75,8 +75,11 @@ AC_CHECK_FUNCS([backtrace_symbols execvpe pipe2])
|
||||
AC_MSG_CHECKING(whether to enable debugging)
|
||||
AC_ARG_ENABLE(debug, [ --enable-debug=[no/yes] turn on debugging (default=no)],, enable_debug=no)
|
||||
if test "x$enable_debug" = "xyes"; then
|
||||
CFLAGS="$CFLAGS -g -O0 -rdynamic"
|
||||
CXXFLAGS="$CXXFLAGS -g -O0 -rdynamic"
|
||||
CFLAGS="$CFLAGS -g -O0 -D_DEBUG"
|
||||
CXXFLAGS="$CXXFLAGS -g -O0 -D_DEBUG"
|
||||
else
|
||||
CFLAGS="$CFLAGS -DNDEBUG"
|
||||
CXXFLAGS="$CXXFLAGS -DNDEBUG"
|
||||
fi
|
||||
AC_MSG_RESULT($enable_debug)
|
||||
|
||||
|
@ -35,12 +35,12 @@ signals2::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnFlushObject;
|
||||
DynamicObject::DynamicObject(const Dictionary::Ptr& serializedObject)
|
||||
: m_EventSafe(false), m_ConfigTx(0)
|
||||
{
|
||||
RegisterAttribute("__name", Attribute_Config);
|
||||
RegisterAttribute("__type", Attribute_Config);
|
||||
RegisterAttribute("__local", Attribute_Config);
|
||||
RegisterAttribute("__abstract", Attribute_Config);
|
||||
RegisterAttribute("__source", Attribute_Local);
|
||||
RegisterAttribute("methods", Attribute_Config);
|
||||
RegisterAttribute("__name", Attribute_Config, &m_Name);
|
||||
RegisterAttribute("__type", Attribute_Config, &m_Type);
|
||||
RegisterAttribute("__local", Attribute_Config, &m_Local);
|
||||
RegisterAttribute("__abstract", Attribute_Config, &m_Abstract);
|
||||
RegisterAttribute("__source", Attribute_Local, &m_Source);
|
||||
RegisterAttribute("methods", Attribute_Config, &m_Methods);
|
||||
|
||||
{
|
||||
ObjectLock olock(serializedObject);
|
||||
@ -50,7 +50,7 @@ DynamicObject::DynamicObject(const Dictionary::Ptr& serializedObject)
|
||||
}
|
||||
|
||||
/* apply config state from the config item/remote update;
|
||||
* The DynamicObject::Create function takes care of restoring
|
||||
* The DynamicType::CreateObject function takes care of restoring
|
||||
* non-config state after the object has been fully constructed */
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
@ -102,22 +102,22 @@ Dictionary::Ptr DynamicObject::BuildUpdate(double sinceTx, int attributeTypes) c
|
||||
Dictionary::Ptr attrs = boost::make_shared<Dictionary>();
|
||||
|
||||
for (it = m_Attributes.begin(); it != m_Attributes.end(); it++) {
|
||||
if (it->second.Type == Attribute_Transient)
|
||||
if (it->second.GetType() == Attribute_Transient)
|
||||
continue;
|
||||
|
||||
if ((it->second.Type & attributeTypes) == 0)
|
||||
if ((it->second.GetType() & attributeTypes) == 0)
|
||||
continue;
|
||||
|
||||
if (it->second.Tx == 0)
|
||||
if (it->second.GetTx() == 0)
|
||||
continue;
|
||||
|
||||
if (it->second.Tx < sinceTx && !(it->second.Type == Attribute_Config && m_ConfigTx >= sinceTx))
|
||||
if (it->second.GetTx() < sinceTx && !(it->second.GetType() == Attribute_Config && m_ConfigTx >= sinceTx))
|
||||
continue;
|
||||
|
||||
Dictionary::Ptr attr = boost::make_shared<Dictionary>();
|
||||
attr->Set("data", it->second.Data);
|
||||
attr->Set("type", it->second.Type);
|
||||
attr->Set("tx", it->second.Tx);
|
||||
attr->Set("data", it->second.GetValue());
|
||||
attr->Set("type", it->second.GetType());
|
||||
attr->Set("tx", it->second.GetTx());
|
||||
|
||||
attrs->Set(it->first, attr);
|
||||
}
|
||||
@ -180,7 +180,7 @@ void DynamicObject::ApplyUpdate(const Dictionary::Ptr& serializedUpdate,
|
||||
RegisterAttribute(it->first, Attribute_Config);
|
||||
|
||||
if (!HasAttribute(it->first))
|
||||
RegisterAttribute(it->first, static_cast<DynamicAttributeType>(type));
|
||||
RegisterAttribute(it->first, static_cast<AttributeType>(type));
|
||||
|
||||
InternalSetAttribute(it->first, data, tx, true);
|
||||
}
|
||||
@ -188,17 +188,19 @@ void DynamicObject::ApplyUpdate(const Dictionary::Ptr& serializedUpdate,
|
||||
}
|
||||
|
||||
void DynamicObject::RegisterAttribute(const String& name,
|
||||
DynamicAttributeType type)
|
||||
AttributeType type, AttributeBase *boundAttribute)
|
||||
{
|
||||
DynamicAttribute attr;
|
||||
attr.Type = type;
|
||||
attr.Tx = 0;
|
||||
AttributeHolder attr(type, boundAttribute);
|
||||
|
||||
pair<DynamicObject::AttributeIterator, bool> tt;
|
||||
tt = m_Attributes.insert(make_pair(name, attr));
|
||||
|
||||
if (!tt.second)
|
||||
tt.first->second.Type = type;
|
||||
if (!tt.second) {
|
||||
tt.first->second.SetType(type);
|
||||
|
||||
if (boundAttribute)
|
||||
tt.first->second.Bind(boundAttribute);
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicObject::Set(const String& name, const Value& data)
|
||||
@ -219,28 +221,27 @@ Value DynamicObject::Get(const String& name) const
|
||||
void DynamicObject::InternalSetAttribute(const String& name, const Value& data,
|
||||
double tx, bool allowEditConfig)
|
||||
{
|
||||
DynamicAttribute attr;
|
||||
attr.Type = Attribute_Transient;
|
||||
attr.Data = data;
|
||||
attr.Tx = tx;
|
||||
|
||||
pair<DynamicObject::AttributeIterator, bool> tt;
|
||||
tt = m_Attributes.insert(make_pair(name, attr));
|
||||
DynamicObject::AttributeIterator it;
|
||||
it = m_Attributes.find(name);
|
||||
|
||||
Value oldValue;
|
||||
|
||||
if (!allowEditConfig && (tt.first->second.Type & Attribute_Config))
|
||||
BOOST_THROW_EXCEPTION(runtime_error("Config properties are immutable: '" + name + "'."));
|
||||
if (it == m_Attributes.end()) {
|
||||
AttributeHolder attr(Attribute_Transient);
|
||||
attr.SetValue(tx, data);
|
||||
|
||||
if (!tt.second && tx >= tt.first->second.Tx) {
|
||||
oldValue = tt.first->second.Data;
|
||||
tt.first->second.Data = data;
|
||||
tt.first->second.Tx = tx;
|
||||
m_Attributes.insert(make_pair(name, attr));
|
||||
} else {
|
||||
if (!allowEditConfig && (it->second.GetType() & Attribute_Config))
|
||||
BOOST_THROW_EXCEPTION(runtime_error("Config properties are immutable: '" + name + "'."));
|
||||
|
||||
oldValue = it->second.GetValue();
|
||||
it->second.SetValue(tx, data);
|
||||
|
||||
if (it->second.GetType() & Attribute_Config)
|
||||
m_ConfigTx = tx;
|
||||
}
|
||||
|
||||
if (tt.first->second.Type & Attribute_Config)
|
||||
m_ConfigTx = tx;
|
||||
|
||||
if (GetEventSafe()) {
|
||||
/* We can't call GetSelf() in the constructor or destructor.
|
||||
* The OnConstructionCompleted() function will take care of adding this
|
||||
@ -269,7 +270,7 @@ Value DynamicObject::InternalGetAttribute(const String& name) const
|
||||
if (it == m_Attributes.end())
|
||||
return Empty;
|
||||
|
||||
return it->second.Data;
|
||||
return it->second.GetValue();
|
||||
}
|
||||
|
||||
bool DynamicObject::HasAttribute(const String& name) const
|
||||
@ -277,57 +278,46 @@ bool DynamicObject::HasAttribute(const String& name) const
|
||||
return (m_Attributes.find(name) != m_Attributes.end());
|
||||
}
|
||||
|
||||
void DynamicObject::ClearAttributesByType(DynamicAttributeType type)
|
||||
void DynamicObject::ClearAttributesByType(AttributeType type)
|
||||
{
|
||||
DynamicObject::AttributeIterator at;
|
||||
for (at = m_Attributes.begin(); at != m_Attributes.end(); at++) {
|
||||
if (at->second.Type != type)
|
||||
if (at->second.GetType() != type)
|
||||
continue;
|
||||
|
||||
at->second.Tx = 0;
|
||||
at->second.Data = Empty;
|
||||
at->second.SetValue(0, Empty);
|
||||
}
|
||||
}
|
||||
|
||||
DynamicType::Ptr DynamicObject::GetType(void) const
|
||||
{
|
||||
String name = Get("__type");
|
||||
return DynamicType::GetByName(name);
|
||||
return DynamicType::GetByName(m_Type);
|
||||
}
|
||||
|
||||
String DynamicObject::GetName(void) const
|
||||
{
|
||||
return Get("__name");
|
||||
return m_Name;
|
||||
}
|
||||
|
||||
bool DynamicObject::IsLocal(void) const
|
||||
{
|
||||
Value value = Get("__local");
|
||||
|
||||
if (value.IsEmpty())
|
||||
return false;
|
||||
|
||||
return (value != 0);
|
||||
return m_Local;
|
||||
}
|
||||
|
||||
bool DynamicObject::IsAbstract(void) const
|
||||
{
|
||||
Value value = Get("__abstract");
|
||||
|
||||
if (value.IsEmpty())
|
||||
return false;
|
||||
|
||||
return (value != 0);
|
||||
return m_Abstract;
|
||||
}
|
||||
|
||||
void DynamicObject::SetSource(const String& value)
|
||||
{
|
||||
Set("__source", value);
|
||||
m_Source = value;
|
||||
Touch("__source");
|
||||
}
|
||||
|
||||
String DynamicObject::GetSource(void) const
|
||||
{
|
||||
return Get("__source");
|
||||
return m_Source;
|
||||
}
|
||||
|
||||
void DynamicObject::Register(void)
|
||||
@ -371,13 +361,9 @@ void DynamicObject::Unregister(void)
|
||||
ScriptTask::Ptr DynamicObject::MakeMethodTask(const String& method,
|
||||
const vector<Value>& arguments)
|
||||
{
|
||||
Value value = Get("methods");
|
||||
|
||||
if (!value.IsObjectType<Dictionary>())
|
||||
return ScriptTask::Ptr();
|
||||
|
||||
String funcName;
|
||||
Dictionary::Ptr methods = value;
|
||||
|
||||
Dictionary::Ptr methods = m_Methods;
|
||||
|
||||
{
|
||||
ObjectLock olock(methods);
|
||||
|
@ -28,7 +28,7 @@ namespace icinga
|
||||
*
|
||||
* @ingroup base
|
||||
*/
|
||||
enum DynamicAttributeType
|
||||
enum AttributeType
|
||||
{
|
||||
Attribute_Transient = 1,
|
||||
|
||||
@ -48,16 +48,142 @@ enum DynamicAttributeType
|
||||
Attribute_All = Attribute_Transient | Attribute_Local | Attribute_Replicated | Attribute_Config
|
||||
};
|
||||
|
||||
class AttributeBase
|
||||
{
|
||||
public:
|
||||
AttributeBase(void)
|
||||
: m_Value()
|
||||
{ }
|
||||
|
||||
void InternalSet(const Value& value)
|
||||
{
|
||||
m_Value = value;
|
||||
}
|
||||
|
||||
const Value& InternalGet(void) const
|
||||
{
|
||||
return m_Value;
|
||||
}
|
||||
|
||||
operator Value(void) const
|
||||
{
|
||||
return InternalGet();
|
||||
}
|
||||
|
||||
bool IsEmpty(void) const
|
||||
{
|
||||
return InternalGet().IsEmpty();
|
||||
}
|
||||
|
||||
private:
|
||||
Value m_Value;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class Attribute : public AttributeBase
|
||||
{
|
||||
public:
|
||||
void Set(const T& value)
|
||||
{
|
||||
InternalSet(value);
|
||||
}
|
||||
|
||||
Attribute<T>& operator=(const T& rhs)
|
||||
{
|
||||
Set(rhs);
|
||||
}
|
||||
|
||||
T Get(void) const
|
||||
{
|
||||
if (IsEmpty())
|
||||
return T();
|
||||
|
||||
return InternalGet();
|
||||
}
|
||||
|
||||
operator T(void) const
|
||||
{
|
||||
return Get();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* An attribute for a DynamicObject.
|
||||
*
|
||||
* @ingroup base
|
||||
*/
|
||||
struct DynamicAttribute
|
||||
struct AttributeHolder
|
||||
{
|
||||
Value Data; /**< The current value of the attribute. */
|
||||
DynamicAttributeType Type; /**< The type of the attribute. */
|
||||
double Tx; /**< The timestamp of the last value change. */
|
||||
AttributeType m_Type; /**< The type of the attribute. */
|
||||
double m_Tx; /**< The timestamp of the last value change. */
|
||||
bool m_OwnsAttribute; /**< Whether we own the Data pointer. */
|
||||
AttributeBase *m_Attribute; /**< The current value of the attribute. */
|
||||
|
||||
AttributeHolder(AttributeType type, AttributeBase *boundAttribute = NULL)
|
||||
: m_Type(type), m_Tx(0)
|
||||
{
|
||||
if (boundAttribute) {
|
||||
m_Attribute = boundAttribute;
|
||||
m_OwnsAttribute = false;
|
||||
} else {
|
||||
m_Attribute = new Attribute<Value>();
|
||||
m_OwnsAttribute = true;
|
||||
}
|
||||
}
|
||||
|
||||
AttributeHolder(const AttributeHolder& other)
|
||||
{
|
||||
m_Type = other.m_Type;
|
||||
m_Tx = other.m_Tx;
|
||||
m_OwnsAttribute = other.m_OwnsAttribute;
|
||||
|
||||
if (other.m_OwnsAttribute) {
|
||||
m_Attribute = new Attribute<Value>();
|
||||
m_Attribute->InternalSet(other.m_Attribute->InternalGet());
|
||||
} else {
|
||||
m_Attribute = other.m_Attribute;
|
||||
}
|
||||
}
|
||||
|
||||
~AttributeHolder(void)
|
||||
{
|
||||
if (m_OwnsAttribute)
|
||||
delete m_Attribute;
|
||||
}
|
||||
|
||||
void Bind(AttributeBase *boundAttribute)
|
||||
{
|
||||
assert(m_OwnsAttribute);
|
||||
boundAttribute->InternalSet(m_Attribute->InternalGet());
|
||||
m_Attribute = boundAttribute;
|
||||
m_OwnsAttribute = false;
|
||||
}
|
||||
|
||||
void SetValue(double tx, const Value& value)
|
||||
{
|
||||
m_Tx = tx;
|
||||
m_Attribute->InternalSet(value);
|
||||
}
|
||||
|
||||
Value GetValue(void) const
|
||||
{
|
||||
return m_Attribute->InternalGet();
|
||||
}
|
||||
|
||||
void SetType(AttributeType type)
|
||||
{
|
||||
m_Type = type;
|
||||
}
|
||||
|
||||
AttributeType GetType(void) const
|
||||
{
|
||||
return m_Type;
|
||||
}
|
||||
|
||||
double GetTx(void) const
|
||||
{
|
||||
return m_Tx;
|
||||
}
|
||||
};
|
||||
|
||||
class DynamicType;
|
||||
@ -74,7 +200,7 @@ public:
|
||||
typedef shared_ptr<DynamicObject> Ptr;
|
||||
typedef weak_ptr<DynamicObject> WeakPtr;
|
||||
|
||||
typedef map<String, DynamicAttribute, string_iless> AttributeMap;
|
||||
typedef map<String, AttributeHolder, string_iless> AttributeMap;
|
||||
typedef AttributeMap::iterator AttributeIterator;
|
||||
typedef AttributeMap::const_iterator AttributeConstIterator;
|
||||
|
||||
@ -86,7 +212,7 @@ public:
|
||||
Dictionary::Ptr BuildUpdate(double sinceTx, int attributeTypes) const;
|
||||
void ApplyUpdate(const Dictionary::Ptr& serializedUpdate, int allowedTypes);
|
||||
|
||||
void RegisterAttribute(const String& name, DynamicAttributeType type);
|
||||
void RegisterAttribute(const String& name, AttributeType type, AttributeBase *boundAttribute = NULL);
|
||||
|
||||
void Set(const String& name, const Value& data);
|
||||
void Touch(const String& name);
|
||||
@ -94,7 +220,9 @@ public:
|
||||
|
||||
bool HasAttribute(const String& name) const;
|
||||
|
||||
void ClearAttributesByType(DynamicAttributeType type);
|
||||
void BindAttribute(const String& name, Value *boundValue);
|
||||
|
||||
void ClearAttributesByType(AttributeType type);
|
||||
|
||||
static signals2::signal<void (const DynamicObject::Ptr&)> OnRegistered;
|
||||
static signals2::signal<void (const DynamicObject::Ptr&)> OnUnregistered;
|
||||
@ -150,6 +278,13 @@ private:
|
||||
map<String, Value, string_iless> m_ModifiedAttributes;
|
||||
double m_ConfigTx;
|
||||
|
||||
Attribute<String> m_Name;
|
||||
Attribute<String> m_Type;
|
||||
Attribute<bool> m_Local;
|
||||
Attribute<bool> m_Abstract;
|
||||
Attribute<String> m_Source;
|
||||
Attribute<Dictionary::Ptr> m_Methods;
|
||||
|
||||
bool m_EventSafe;
|
||||
|
||||
static double m_CurrentTx;
|
||||
|
@ -101,6 +101,12 @@ void DynamicType::RegisterObject(const DynamicObject::Ptr& object)
|
||||
|
||||
/* notify the object that it's been registered */
|
||||
object->OnRegistrationCompleted();
|
||||
|
||||
{
|
||||
ObjectLock olock(object);
|
||||
object->Flush();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void DynamicType::UnregisterObject(const DynamicObject::Ptr& object)
|
||||
@ -148,7 +154,7 @@ DynamicObject::Ptr DynamicType::CreateObject(const Dictionary::Ptr& serializedUp
|
||||
|
||||
/* register attributes */
|
||||
String name;
|
||||
DynamicAttributeType type;
|
||||
AttributeType type;
|
||||
BOOST_FOREACH(tuples::tie(name, type), m_Attributes)
|
||||
object->RegisterAttribute(name, type);
|
||||
|
||||
@ -169,7 +175,7 @@ bool DynamicType::TypeExists(const String& name)
|
||||
return (GetByName(name));
|
||||
}
|
||||
|
||||
void DynamicType::AddAttribute(const String& name, DynamicAttributeType type)
|
||||
void DynamicType::AddAttribute(const String& name, AttributeType type)
|
||||
{
|
||||
m_Attributes[name] = type;
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ namespace icinga
|
||||
struct AttributeDescription
|
||||
{
|
||||
String Name;
|
||||
DynamicAttributeType Type;
|
||||
AttributeType Type;
|
||||
};
|
||||
|
||||
class I2_BASE_API DynamicType : public Object
|
||||
@ -57,7 +57,7 @@ public:
|
||||
|
||||
static set<DynamicObject::Ptr> GetObjects(const String& type);
|
||||
|
||||
void AddAttribute(const String& name, DynamicAttributeType type);
|
||||
void AddAttribute(const String& name, AttributeType type);
|
||||
void RemoveAttribute(const String& name);
|
||||
bool HasAttribute(const String& name);
|
||||
|
||||
@ -66,7 +66,7 @@ public:
|
||||
private:
|
||||
String m_Name;
|
||||
ObjectFactory m_ObjectFactory;
|
||||
map<String, DynamicAttributeType> m_Attributes;
|
||||
map<String, AttributeType> m_Attributes;
|
||||
|
||||
typedef map<String, DynamicObject::Ptr, string_iless> ObjectMap;
|
||||
typedef set<DynamicObject::Ptr> ObjectSet;
|
||||
|
@ -34,6 +34,11 @@ EventQueue::EventQueue(void)
|
||||
|
||||
for (int i = 0; i < thread_count; i++)
|
||||
m_Threads.create_thread(boost::bind(&EventQueue::QueueThreadProc, this));
|
||||
|
||||
m_ReportTimer = boost::make_shared<Timer>();
|
||||
m_ReportTimer->OnTimerExpired.connect(boost::bind(&EventQueue::ReportTimerHandler, this));
|
||||
m_ReportTimer->SetInterval(5);
|
||||
m_ReportTimer->Start();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -41,6 +46,8 @@ EventQueue::EventQueue(void)
|
||||
*/
|
||||
EventQueue::~EventQueue(void)
|
||||
{
|
||||
m_ReportTimer->Stop();
|
||||
|
||||
Stop();
|
||||
Join();
|
||||
}
|
||||
@ -114,11 +121,17 @@ void EventQueue::Post(const EventQueue::Callback& callback)
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
m_Events.push_back(callback);
|
||||
m_CV.notify_one();
|
||||
|
||||
int pending = m_Events.size();
|
||||
double now = Utility::GetTime();
|
||||
if (pending > 1000 && now - m_LastReport > 5) {
|
||||
Logger::Write(LogCritical, "base", "More than 1000 pending events: " + Convert::ToString(pending));
|
||||
m_LastReport = now;
|
||||
}
|
||||
}
|
||||
|
||||
void EventQueue::ReportTimerHandler(void)
|
||||
{
|
||||
int pending;
|
||||
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
pending = m_Events.size();
|
||||
}
|
||||
|
||||
if (pending > 1000)
|
||||
Logger::Write(LogCritical, "base", "More than 1000 pending events: " + Convert::ToString(pending));
|
||||
}
|
||||
|
@ -23,6 +23,8 @@
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
class Timer;
|
||||
|
||||
/**
|
||||
* An event queue.
|
||||
*
|
||||
@ -48,10 +50,13 @@ private:
|
||||
condition_variable m_CV;
|
||||
|
||||
double m_LastReport;
|
||||
shared_ptr<Timer> m_ReportTimer;
|
||||
|
||||
bool m_Stopped;
|
||||
vector<Callback> m_Events;
|
||||
|
||||
void QueueThreadProc(void);
|
||||
void ReportTimerHandler(void);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -31,10 +31,14 @@ REGISTER_TYPE(Logger, NULL);
|
||||
Logger::Logger(const Dictionary::Ptr& properties)
|
||||
: DynamicObject(properties)
|
||||
{
|
||||
RegisterAttribute("type", Attribute_Config, &m_Type);
|
||||
RegisterAttribute("path", Attribute_Config, &m_Path);
|
||||
RegisterAttribute("severity", Attribute_Config, &m_Severity);
|
||||
|
||||
if (!IsLocal())
|
||||
BOOST_THROW_EXCEPTION(runtime_error("Logger objects must be local."));
|
||||
|
||||
String type = Get("type");
|
||||
String type = m_Type;
|
||||
if (type.IsEmpty())
|
||||
BOOST_THROW_EXCEPTION(runtime_error("Logger objects must have a 'type' property."));
|
||||
|
||||
@ -47,7 +51,7 @@ Logger::Logger(const Dictionary::Ptr& properties)
|
||||
BOOST_THROW_EXCEPTION(invalid_argument("Syslog is not supported on Windows."));
|
||||
#endif /* _WIN32 */
|
||||
} else if (type == "file") {
|
||||
String path = Get("path");
|
||||
String path = m_Path;
|
||||
if (path.IsEmpty())
|
||||
BOOST_THROW_EXCEPTION(invalid_argument("'log' object of type 'file' must have a 'path' property"));
|
||||
|
||||
@ -91,7 +95,7 @@ void Logger::Write(LogSeverity severity, const String& facility,
|
||||
*/
|
||||
LogSeverity Logger::GetMinSeverity(void) const
|
||||
{
|
||||
String severity = Get("severity");
|
||||
String severity = m_Severity;
|
||||
if (severity.IsEmpty())
|
||||
return LogInformation;
|
||||
else
|
||||
|
@ -98,6 +98,10 @@ public:
|
||||
LogSeverity GetMinSeverity(void) const;
|
||||
|
||||
private:
|
||||
Attribute<String> m_Type;
|
||||
Attribute<String> m_Path;
|
||||
Attribute<String> m_Severity;
|
||||
|
||||
LogSeverity m_MinSeverity;
|
||||
ILogger::Ptr m_Impl;
|
||||
|
||||
|
@ -30,7 +30,10 @@ REGISTER_TYPE(Script, NULL);
|
||||
*/
|
||||
Script::Script(const Dictionary::Ptr& properties)
|
||||
: DynamicObject(properties)
|
||||
{ }
|
||||
{
|
||||
RegisterAttribute("language", Attribute_Config, &m_Language);
|
||||
RegisterAttribute("code", Attribute_Config, &m_Code);
|
||||
}
|
||||
|
||||
void Script::OnRegistrationCompleted(void)
|
||||
{
|
||||
@ -41,12 +44,12 @@ void Script::OnRegistrationCompleted(void)
|
||||
|
||||
String Script::GetLanguage(void) const
|
||||
{
|
||||
return Get("language");
|
||||
return m_Language;
|
||||
}
|
||||
|
||||
String Script::GetCode(void) const
|
||||
{
|
||||
return Get("code");
|
||||
return m_Code;
|
||||
}
|
||||
|
||||
void Script::OnAttributeUpdate(const String& name, const Value& oldValue)
|
||||
|
@ -46,6 +46,9 @@ protected:
|
||||
virtual void OnAttributeUpdate(const String& name, const Value& oldValue);
|
||||
|
||||
private:
|
||||
Attribute<String> m_Language;
|
||||
Attribute<String> m_Code;
|
||||
|
||||
shared_ptr<ScriptInterpreter> m_Interpreter;
|
||||
|
||||
void SpawnInterpreter(void);
|
||||
|
@ -270,6 +270,8 @@ void Timer::TimerThreadProc(void)
|
||||
timer->m_Started = false;
|
||||
m_Timers.erase(timer);
|
||||
|
||||
lock.unlock();
|
||||
|
||||
/* Asynchronously call the timer. */
|
||||
Application::GetEQ().Post(boost::bind(&Timer::Call, timer));
|
||||
}
|
||||
|
@ -21,42 +21,41 @@
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
boost::mutex Host::m_Mutex;
|
||||
map<String, map<String, weak_ptr<Service> > > Host::m_ServicesCache;
|
||||
bool Host::m_ServicesCacheValid = true;
|
||||
|
||||
REGISTER_SCRIPTFUNCTION("ValidateServiceDictionary", &Host::ValidateServiceDictionary);
|
||||
|
||||
static AttributeDescription hostAttributes[] = {
|
||||
{ "slave_services", Attribute_Transient }
|
||||
};
|
||||
|
||||
REGISTER_TYPE(Host, hostAttributes);
|
||||
REGISTER_TYPE(Host, NULL);
|
||||
|
||||
Host::Host(const Dictionary::Ptr& properties)
|
||||
: DynamicObject(properties)
|
||||
{ }
|
||||
{
|
||||
RegisterAttribute("display_name", Attribute_Config, &m_DisplayName);
|
||||
RegisterAttribute("hostgroups", Attribute_Config, &m_HostGroups);
|
||||
RegisterAttribute("macros", Attribute_Config, &m_Macros);
|
||||
RegisterAttribute("hostdependencies", Attribute_Config, &m_HostDependencies);
|
||||
RegisterAttribute("servicedependencies", Attribute_Config, &m_ServiceDependencies);
|
||||
RegisterAttribute("hostcheck", Attribute_Config, &m_HostCheck);
|
||||
|
||||
}
|
||||
|
||||
void Host::OnRegistrationCompleted(void)
|
||||
{
|
||||
DynamicObject::OnRegistrationCompleted();
|
||||
|
||||
HostGroup::InvalidateMembersCache();
|
||||
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
UpdateSlaveServices();
|
||||
}
|
||||
Host::UpdateSlaveServices(GetSelf());
|
||||
}
|
||||
|
||||
Host::~Host(void)
|
||||
{
|
||||
HostGroup::InvalidateMembersCache();
|
||||
|
||||
Dictionary::Ptr services = Get("slave_services");
|
||||
|
||||
if (services) {
|
||||
if (m_SlaveServices) {
|
||||
ConfigItem::Ptr service;
|
||||
BOOST_FOREACH(tie(tuples::ignore, service), services) {
|
||||
BOOST_FOREACH(tie(tuples::ignore, service), m_SlaveServices) {
|
||||
service->Unregister();
|
||||
}
|
||||
}
|
||||
@ -64,9 +63,8 @@ Host::~Host(void)
|
||||
|
||||
String Host::GetDisplayName(void) const
|
||||
{
|
||||
String value = Get("display_name");
|
||||
if (!value.IsEmpty())
|
||||
return value;
|
||||
if (!m_DisplayName.IsEmpty())
|
||||
return m_DisplayName;
|
||||
else
|
||||
return GetName();
|
||||
}
|
||||
@ -94,27 +92,27 @@ Host::Ptr Host::GetByName(const String& name)
|
||||
|
||||
Dictionary::Ptr Host::GetGroups(void) const
|
||||
{
|
||||
return Get("hostgroups");
|
||||
return m_HostGroups;;
|
||||
}
|
||||
|
||||
Dictionary::Ptr Host::GetMacros(void) const
|
||||
{
|
||||
return Get("macros");
|
||||
return m_Macros;
|
||||
}
|
||||
|
||||
Dictionary::Ptr Host::GetHostDependencies(void) const
|
||||
{
|
||||
return Get("hostdependencies");
|
||||
return m_HostDependencies;;
|
||||
}
|
||||
|
||||
Dictionary::Ptr Host::GetServiceDependencies(void) const
|
||||
{
|
||||
return Get("servicedependencies");
|
||||
return m_ServiceDependencies;
|
||||
}
|
||||
|
||||
String Host::GetHostCheck(void) const
|
||||
{
|
||||
return Get("hostcheck");
|
||||
return m_HostCheck;
|
||||
}
|
||||
|
||||
bool Host::IsReachable(const Host::Ptr& self)
|
||||
@ -213,21 +211,36 @@ static void CopyServiceAttributes(TDict serviceDesc, const ConfigItemBuilder::Pt
|
||||
}
|
||||
}
|
||||
|
||||
void Host::UpdateSlaveServices(void)
|
||||
void Host::UpdateSlaveServices(const Host::Ptr& self)
|
||||
{
|
||||
ConfigItem::Ptr item = ConfigItem::GetObject("Host", GetName());
|
||||
ConfigItem::Ptr item;
|
||||
Dictionary::Ptr oldServices, newServices, serviceDescs;
|
||||
String host_name;
|
||||
|
||||
/* Don't create slave services unless we own this object
|
||||
* and it's not a template. */
|
||||
if (!item || IsAbstract())
|
||||
return;
|
||||
{
|
||||
ObjectLock olock(self);
|
||||
|
||||
Dictionary::Ptr oldServices = Get("slave_services");
|
||||
host_name = self->GetName();
|
||||
|
||||
item = ConfigItem::GetObject("Host", host_name);
|
||||
|
||||
/* Don't create slave services unless we own this object
|
||||
* and it's not a template. */
|
||||
if (!item || self->IsAbstract())
|
||||
return;
|
||||
|
||||
oldServices = self->m_SlaveServices;
|
||||
serviceDescs = self->Get("services");
|
||||
}
|
||||
|
||||
Dictionary::Ptr newServices;
|
||||
newServices = boost::make_shared<Dictionary>();
|
||||
|
||||
Dictionary::Ptr serviceDescs = Get("services");
|
||||
DebugInfo debug_info;
|
||||
|
||||
{
|
||||
ObjectLock olock(item);
|
||||
debug_info = item->GetDebugInfo();
|
||||
}
|
||||
|
||||
if (serviceDescs) {
|
||||
String svcname;
|
||||
@ -237,17 +250,17 @@ void Host::UpdateSlaveServices(void)
|
||||
svcname = svcdesc;
|
||||
|
||||
stringstream namebuf;
|
||||
namebuf << GetName() << "-" << svcname;
|
||||
namebuf << host_name << "-" << svcname;
|
||||
String name = namebuf.str();
|
||||
|
||||
ConfigItemBuilder::Ptr builder = boost::make_shared<ConfigItemBuilder>(item->GetDebugInfo());
|
||||
ConfigItemBuilder::Ptr builder = boost::make_shared<ConfigItemBuilder>(debug_info);
|
||||
builder->SetType("Service");
|
||||
builder->SetName(name);
|
||||
builder->AddExpression("host_name", OperatorSet, GetName());
|
||||
builder->AddExpression("host_name", OperatorSet, host_name);
|
||||
builder->AddExpression("display_name", OperatorSet, svcname);
|
||||
builder->AddExpression("short_name", OperatorSet, svcname);
|
||||
|
||||
CopyServiceAttributes<false>(this, builder);
|
||||
CopyServiceAttributes<false>(self, builder);
|
||||
|
||||
if (svcdesc.IsScalar()) {
|
||||
builder->AddParent(svcdesc);
|
||||
@ -271,7 +284,7 @@ void Host::UpdateSlaveServices(void)
|
||||
}
|
||||
|
||||
ConfigItem::Ptr serviceItem = builder->Compile();
|
||||
ConfigItem::Commit(serviceItem);
|
||||
DynamicObject::Ptr dobj = ConfigItem::Commit(serviceItem);
|
||||
|
||||
newServices->Set(name, serviceItem);
|
||||
}
|
||||
@ -290,7 +303,7 @@ void Host::UpdateSlaveServices(void)
|
||||
|
||||
newServices->Seal();
|
||||
|
||||
Set("slave_services", newServices);
|
||||
self->Set("slave_services", newServices);
|
||||
}
|
||||
|
||||
void Host::OnAttributeChanged(const String& name, const Value&)
|
||||
@ -298,8 +311,7 @@ void Host::OnAttributeChanged(const String& name, const Value&)
|
||||
if (name == "hostgroups")
|
||||
HostGroup::InvalidateMembersCache();
|
||||
else if (name == "services") {
|
||||
ObjectLock olock(this);
|
||||
UpdateSlaveServices();
|
||||
UpdateSlaveServices(GetSelf());
|
||||
} else if (name == "notifications") {
|
||||
set<Service::Ptr> services;
|
||||
|
||||
@ -309,9 +321,11 @@ void Host::OnAttributeChanged(const String& name, const Value&)
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const Service::Ptr& service, services) {
|
||||
ObjectLock olock(service);
|
||||
service->UpdateSlaveNotifications();
|
||||
Service::UpdateSlaveNotifications(service);
|
||||
}
|
||||
} else if (name == "hostcheck") {
|
||||
ObjectLock olock(this);
|
||||
m_HostCheckService = GetServiceByShortName(GetHostCheck());
|
||||
}
|
||||
}
|
||||
|
||||
@ -319,6 +333,8 @@ set<Service::Ptr> Host::GetServices(void) const
|
||||
{
|
||||
set<Service::Ptr> services;
|
||||
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
|
||||
ValidateServicesCache();
|
||||
|
||||
Service::WeakPtr wservice;
|
||||
@ -336,10 +352,14 @@ set<Service::Ptr> Host::GetServices(void) const
|
||||
|
||||
void Host::InvalidateServicesCache(void)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
m_ServicesCacheValid = false;
|
||||
m_ServicesCache.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @threadsafety Caller must hold m_Mutex.
|
||||
*/
|
||||
void Host::ValidateServicesCache(void)
|
||||
{
|
||||
if (m_ServicesCacheValid)
|
||||
@ -350,9 +370,25 @@ void Host::ValidateServicesCache(void)
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Service")) {
|
||||
const Service::Ptr& service = static_pointer_cast<Service>(object);
|
||||
|
||||
Host::Ptr host;
|
||||
String short_name;
|
||||
|
||||
{
|
||||
ObjectLock olock(service);
|
||||
host = service->GetHost();
|
||||
short_name = service->GetShortName();
|
||||
}
|
||||
|
||||
String host_name;
|
||||
|
||||
{
|
||||
ObjectLock olock(host);
|
||||
host_name = host->GetName();
|
||||
}
|
||||
|
||||
// TODO: assert for duplicate short_names
|
||||
|
||||
m_ServicesCache[service->GetHost()->GetName()][service->GetShortName()] = service;
|
||||
m_ServicesCache[host_name][short_name] = service;
|
||||
}
|
||||
|
||||
m_ServicesCacheValid = true;
|
||||
@ -411,15 +447,20 @@ void Host::ValidateServiceDictionary(const ScriptTask::Ptr& task, const vector<V
|
||||
Service::Ptr Host::GetServiceByShortName(const Value& name) const
|
||||
{
|
||||
if (name.IsScalar()) {
|
||||
ValidateServicesCache();
|
||||
|
||||
map<String, weak_ptr<Service> >& services = m_ServicesCache[GetName()];
|
||||
map<String, weak_ptr<Service> >::iterator it = services.find(name);
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
|
||||
if (it != services.end()) {
|
||||
Service::Ptr service = it->second.lock();
|
||||
assert(service);
|
||||
return service;
|
||||
ValidateServicesCache();
|
||||
|
||||
map<String, weak_ptr<Service> >& services = m_ServicesCache[GetName()];
|
||||
map<String, weak_ptr<Service> >::iterator it = services.find(name);
|
||||
|
||||
if (it != services.end()) {
|
||||
Service::Ptr service = it->second.lock();
|
||||
assert(service);
|
||||
return service;
|
||||
}
|
||||
}
|
||||
|
||||
return Service::GetByName(name);
|
||||
@ -452,17 +493,7 @@ set<Host::Ptr> Host::GetParentHosts(void) const
|
||||
|
||||
Service::Ptr Host::GetHostCheckService(void) const
|
||||
{
|
||||
String hostcheck = GetHostCheck();
|
||||
|
||||
if (hostcheck.IsEmpty())
|
||||
return Service::Ptr();
|
||||
|
||||
Service::Ptr service = GetServiceByShortName(hostcheck);
|
||||
|
||||
if (service->GetHost()->GetName() != GetName())
|
||||
BOOST_THROW_EXCEPTION(runtime_error("Hostcheck service refers to another host's service."));
|
||||
|
||||
return service;
|
||||
return m_HostCheckService.lock();
|
||||
}
|
||||
|
||||
set<Service::Ptr> Host::GetParentServices(void) const
|
||||
|
@ -71,12 +71,23 @@ protected:
|
||||
void OnAttributeChanged(const String& name, const Value& oldValue);
|
||||
|
||||
private:
|
||||
Attribute<String> m_DisplayName;
|
||||
Attribute<Dictionary::Ptr> m_HostGroups;
|
||||
Attribute<Dictionary::Ptr> m_Macros;
|
||||
Attribute<Dictionary::Ptr> m_HostDependencies;
|
||||
Attribute<Dictionary::Ptr> m_ServiceDependencies;
|
||||
Attribute<String> m_HostCheck;
|
||||
Dictionary::Ptr m_SlaveServices;
|
||||
|
||||
static boost::mutex m_Mutex;
|
||||
static map<String, map<String, weak_ptr<Service> > > m_ServicesCache;
|
||||
static bool m_ServicesCacheValid;
|
||||
|
||||
void UpdateSlaveServices(void);
|
||||
static void UpdateSlaveServices(const Host::Ptr& self);
|
||||
|
||||
static void ValidateServicesCache(void);
|
||||
|
||||
weak_ptr<Service> m_HostCheckService;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -29,26 +29,28 @@ REGISTER_TYPE(HostGroup, NULL);
|
||||
|
||||
HostGroup::HostGroup(const Dictionary::Ptr& properties)
|
||||
: DynamicObject(properties)
|
||||
{ }
|
||||
{
|
||||
RegisterAttribute("display_name", Attribute_Config, &m_DisplayName);
|
||||
RegisterAttribute("notes_url", Attribute_Config, &m_NotesUrl);
|
||||
RegisterAttribute("action_url", Attribute_Config, &m_ActionUrl);
|
||||
}
|
||||
|
||||
String HostGroup::GetDisplayName(void) const
|
||||
{
|
||||
String value = Get("display_name");
|
||||
|
||||
if (!value.IsEmpty())
|
||||
return value;
|
||||
if (!m_DisplayName.IsEmpty())
|
||||
return m_DisplayName;
|
||||
else
|
||||
return GetName();
|
||||
}
|
||||
|
||||
String HostGroup::GetNotesUrl(void) const
|
||||
{
|
||||
return Get("notes_url");
|
||||
return m_NotesUrl;
|
||||
}
|
||||
|
||||
String HostGroup::GetActionUrl(void) const
|
||||
{
|
||||
return Get("action_url");
|
||||
return m_ActionUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -47,6 +47,10 @@ public:
|
||||
static void InvalidateMembersCache(void);
|
||||
|
||||
private:
|
||||
Attribute<String> m_DisplayName;
|
||||
Attribute<String> m_NotesUrl;
|
||||
Attribute<String> m_ActionUrl;
|
||||
|
||||
static boost::mutex m_Mutex;
|
||||
static map<String, vector<weak_ptr<Host> > > m_MembersCache;
|
||||
static bool m_MembersCacheValid;
|
||||
|
@ -30,7 +30,15 @@ REGISTER_TYPE(IcingaApplication, NULL);
|
||||
|
||||
IcingaApplication::IcingaApplication(const Dictionary::Ptr& serializedUpdate)
|
||||
: Application(serializedUpdate)
|
||||
{ }
|
||||
{
|
||||
RegisterAttribute("cert_path", Attribute_Config, &m_CertPath);
|
||||
RegisterAttribute("ca_path", Attribute_Config, &m_CAPath);
|
||||
RegisterAttribute("node", Attribute_Config, &m_Node);
|
||||
RegisterAttribute("service", Attribute_Config, &m_Service);
|
||||
RegisterAttribute("pid_path", Attribute_Config, &m_PidPath);
|
||||
RegisterAttribute("state_path", Attribute_Config, &m_StatePath);
|
||||
RegisterAttribute("macros", Attribute_Config, &m_Macros);
|
||||
}
|
||||
|
||||
/**
|
||||
* The entry point for the Icinga application.
|
||||
@ -96,47 +104,43 @@ IcingaApplication::Ptr IcingaApplication::GetInstance(void)
|
||||
|
||||
String IcingaApplication::GetCertificateFile(void) const
|
||||
{
|
||||
return Get("cert_path");
|
||||
return m_CertPath;
|
||||
}
|
||||
|
||||
String IcingaApplication::GetCAFile(void) const
|
||||
{
|
||||
return Get("ca_path");
|
||||
return m_CAPath;
|
||||
}
|
||||
|
||||
String IcingaApplication::GetNode(void) const
|
||||
{
|
||||
return Get("node");
|
||||
return m_Node;
|
||||
}
|
||||
|
||||
String IcingaApplication::GetService(void) const
|
||||
{
|
||||
return Get("service");
|
||||
return m_Service;
|
||||
}
|
||||
|
||||
String IcingaApplication::GetPidPath(void) const
|
||||
{
|
||||
Value pidPath = Get("pid_path");
|
||||
|
||||
if (pidPath.IsEmpty())
|
||||
pidPath = Application::GetLocalStateDir() + "/run/icinga2.pid";
|
||||
|
||||
return pidPath;
|
||||
if (m_PidPath.IsEmpty())
|
||||
return Application::GetLocalStateDir() + "/run/icinga2.pid";
|
||||
else
|
||||
return m_PidPath;
|
||||
}
|
||||
|
||||
String IcingaApplication::GetStatePath(void) const
|
||||
{
|
||||
Value statePath = Get("state_path");
|
||||
|
||||
if (statePath.IsEmpty())
|
||||
statePath = Application::GetLocalStateDir() + "/lib/icinga2/icinga2.state";
|
||||
|
||||
return statePath;
|
||||
if (m_PidPath.IsEmpty())
|
||||
return Application::GetLocalStateDir() + "/lib/icinga2/icinga2.state";
|
||||
else
|
||||
return m_PidPath;
|
||||
}
|
||||
|
||||
Dictionary::Ptr IcingaApplication::GetMacros(void) const
|
||||
{
|
||||
return Get("macros");
|
||||
return m_Macros;
|
||||
}
|
||||
|
||||
double IcingaApplication::GetStartTime(void) const
|
||||
|
@ -54,6 +54,14 @@ public:
|
||||
static Dictionary::Ptr CalculateDynamicMacros(const IcingaApplication::Ptr& self);
|
||||
|
||||
private:
|
||||
Attribute<String> m_CertPath;
|
||||
Attribute<String> m_CAPath;
|
||||
Attribute<String> m_Node;
|
||||
Attribute<String> m_Service;
|
||||
Attribute<String> m_PidPath;
|
||||
Attribute<String> m_StatePath;
|
||||
Attribute<Dictionary::Ptr> m_Macros;
|
||||
|
||||
shared_ptr<SSL_CTX> m_SSLContext;
|
||||
|
||||
double m_StartTime;
|
||||
|
@ -26,6 +26,12 @@ REGISTER_TYPE(Notification, NULL);
|
||||
Notification::Notification(const Dictionary::Ptr& properties)
|
||||
: DynamicObject(properties)
|
||||
{
|
||||
RegisterAttribute("notification_command", Attribute_Config, &m_NotificationCommand);
|
||||
RegisterAttribute("macros", Attribute_Config, &m_Macros);
|
||||
RegisterAttribute("users", Attribute_Config, &m_Users);
|
||||
RegisterAttribute("host_name", Attribute_Config, &m_HostName);
|
||||
RegisterAttribute("service", Attribute_Config, &m_Service);
|
||||
|
||||
Service::InvalidateNotificationsCache();
|
||||
}
|
||||
|
||||
@ -51,30 +57,29 @@ Notification::Ptr Notification::GetByName(const String& name)
|
||||
|
||||
Service::Ptr Notification::GetService(void) const
|
||||
{
|
||||
Host::Ptr host = Host::GetByName(Get("host_name"));
|
||||
String service = Get("service");
|
||||
Host::Ptr host = Host::GetByName(m_HostName);
|
||||
|
||||
if (service.IsEmpty())
|
||||
if (m_Service.IsEmpty())
|
||||
return host->GetHostCheckService();
|
||||
else
|
||||
return host->GetServiceByShortName(service);
|
||||
return host->GetServiceByShortName(m_Service);
|
||||
}
|
||||
|
||||
Value Notification::GetNotificationCommand(void) const
|
||||
{
|
||||
return Get("notification_command");
|
||||
return m_NotificationCommand;
|
||||
}
|
||||
|
||||
Dictionary::Ptr Notification::GetMacros(void) const
|
||||
{
|
||||
return Get("macros");
|
||||
return m_Macros;
|
||||
}
|
||||
|
||||
set<User::Ptr> Notification::GetUsers(void) const
|
||||
{
|
||||
set<User::Ptr> result;
|
||||
|
||||
Dictionary::Ptr users = Get("users");
|
||||
Dictionary::Ptr users = m_Users;
|
||||
|
||||
if (users) {
|
||||
String name;
|
||||
|
@ -71,6 +71,12 @@ protected:
|
||||
void OnAttributeChanged(const String& name, const Value& oldValue);
|
||||
|
||||
private:
|
||||
Attribute<Value> m_NotificationCommand;
|
||||
Attribute<Dictionary::Ptr> m_Macros;
|
||||
Attribute<Dictionary::Ptr> m_Users;
|
||||
Attribute<String> m_HostName;
|
||||
Attribute<String> m_Service;
|
||||
|
||||
set<ScriptTask::Ptr> m_Tasks;
|
||||
|
||||
void NotificationCompletedHandler(const ScriptTask::Ptr& task);
|
||||
|
@ -30,96 +30,64 @@ signals2::signal<void (const Service::Ptr&, const Value&)> Service::OnNextCheckC
|
||||
|
||||
Value Service::GetCheckCommand(void) const
|
||||
{
|
||||
return Get("check_command");
|
||||
return m_CheckCommand;
|
||||
}
|
||||
|
||||
long Service::GetMaxCheckAttempts(void) const
|
||||
{
|
||||
Value value = Get("max_check_attempts");
|
||||
|
||||
if (value.IsEmpty())
|
||||
if (m_MaxCheckAttempts.IsEmpty())
|
||||
return DefaultMaxCheckAttempts;
|
||||
|
||||
return value;
|
||||
return m_MaxCheckAttempts;
|
||||
}
|
||||
|
||||
double Service::GetCheckInterval(void) const
|
||||
{
|
||||
Value value = Get("check_interval");
|
||||
|
||||
if (value.IsEmpty())
|
||||
if (m_CheckInterval.IsEmpty())
|
||||
return DefaultCheckInterval;
|
||||
|
||||
return value;
|
||||
return m_CheckInterval;
|
||||
}
|
||||
|
||||
double Service::GetRetryInterval(void) const
|
||||
{
|
||||
Value value = Get("retry_interval");
|
||||
|
||||
if (value.IsEmpty())
|
||||
if (m_RetryInterval.IsEmpty())
|
||||
return GetCheckInterval() / CheckIntervalDivisor;
|
||||
|
||||
return value;
|
||||
return m_RetryInterval;
|
||||
}
|
||||
|
||||
Dictionary::Ptr Service::GetCheckers(void) const
|
||||
{
|
||||
return Get("checkers");
|
||||
return m_Checkers;
|
||||
}
|
||||
|
||||
void Service::SetSchedulingOffset(long offset)
|
||||
{
|
||||
Set("scheduling_offset", offset);
|
||||
m_SchedulingOffset = offset;
|
||||
}
|
||||
|
||||
long Service::GetSchedulingOffset(void)
|
||||
{
|
||||
Value value = Get("scheduling_offset");
|
||||
|
||||
if (value.IsEmpty()) {
|
||||
value = rand();
|
||||
SetSchedulingOffset(value);
|
||||
}
|
||||
|
||||
return value;
|
||||
return m_SchedulingOffset;
|
||||
}
|
||||
|
||||
void Service::SetFirstCheck(bool first)
|
||||
{
|
||||
Set("first_check", first ? 1 : 0);
|
||||
}
|
||||
|
||||
bool Service::GetFirstCheck(void) const
|
||||
{
|
||||
Value value = Get("first_check");
|
||||
|
||||
if (value.IsEmpty())
|
||||
return true;
|
||||
|
||||
return static_cast<long>(value);
|
||||
}
|
||||
|
||||
|
||||
void Service::SetNextCheck(double nextCheck)
|
||||
{
|
||||
Set("next_check", nextCheck);
|
||||
m_NextCheck = nextCheck;
|
||||
Touch("next_check");
|
||||
}
|
||||
|
||||
double Service::GetNextCheck(void)
|
||||
{
|
||||
Value value = Get("next_check");
|
||||
|
||||
if (value.IsEmpty()) {
|
||||
if (m_NextCheck.IsEmpty()) {
|
||||
UpdateNextCheck();
|
||||
|
||||
value = Get("next_check");
|
||||
|
||||
if (value.IsEmpty())
|
||||
if (m_NextCheck.IsEmpty())
|
||||
BOOST_THROW_EXCEPTION(runtime_error("Failed to schedule next check."));
|
||||
}
|
||||
|
||||
return value;
|
||||
return m_NextCheck;
|
||||
}
|
||||
|
||||
void Service::UpdateNextCheck(void)
|
||||
@ -140,146 +108,140 @@ void Service::UpdateNextCheck(void)
|
||||
SetNextCheck(now - adj + interval);
|
||||
}
|
||||
|
||||
void Service::SetChecker(const String& checker)
|
||||
void Service::SetCurrentChecker(const String& checker)
|
||||
{
|
||||
Set("checker", checker);
|
||||
m_CurrentChecker = checker;
|
||||
Touch("current_checker");
|
||||
}
|
||||
|
||||
String Service::GetChecker(void) const
|
||||
String Service::GetCurrentChecker(void) const
|
||||
{
|
||||
return Get("checker");
|
||||
return m_CurrentChecker;
|
||||
}
|
||||
|
||||
void Service::SetCurrentCheckAttempt(long attempt)
|
||||
{
|
||||
Set("check_attempt", attempt);
|
||||
m_CheckAttempt = attempt;
|
||||
Touch("check_attempt");
|
||||
}
|
||||
|
||||
long Service::GetCurrentCheckAttempt(void) const
|
||||
{
|
||||
Value value = Get("check_attempt");
|
||||
|
||||
if (value.IsEmpty())
|
||||
if (m_CheckAttempt.IsEmpty())
|
||||
return 1;
|
||||
|
||||
return value;
|
||||
return m_CheckAttempt;
|
||||
}
|
||||
|
||||
void Service::SetState(ServiceState state)
|
||||
{
|
||||
Set("state", static_cast<long>(state));
|
||||
m_State = static_cast<long>(state);
|
||||
Touch("state");
|
||||
}
|
||||
|
||||
ServiceState Service::GetState(void) const
|
||||
{
|
||||
Value value = Get("state");
|
||||
|
||||
if (value.IsEmpty())
|
||||
if (m_State.IsEmpty())
|
||||
return StateUnknown;
|
||||
|
||||
int ivalue = static_cast<int>(value);
|
||||
int ivalue = static_cast<int>(m_State);
|
||||
return static_cast<ServiceState>(ivalue);
|
||||
}
|
||||
|
||||
void Service::SetStateType(ServiceStateType type)
|
||||
{
|
||||
Set("state_type", static_cast<long>(type));
|
||||
m_StateType = static_cast<long>(type);
|
||||
Touch("state_type");
|
||||
}
|
||||
|
||||
ServiceStateType Service::GetStateType(void) const
|
||||
{
|
||||
Value value = Get("state_type");
|
||||
|
||||
if (value.IsEmpty())
|
||||
if (m_StateType.IsEmpty())
|
||||
return StateTypeSoft;
|
||||
|
||||
int ivalue = static_cast<int>(value);
|
||||
int ivalue = static_cast<int>(m_StateType);
|
||||
return static_cast<ServiceStateType>(ivalue);
|
||||
}
|
||||
|
||||
void Service::SetLastCheckResult(const Dictionary::Ptr& result)
|
||||
{
|
||||
Set("last_result", result);
|
||||
m_LastResult = result;
|
||||
Touch("last_result");
|
||||
}
|
||||
|
||||
Dictionary::Ptr Service::GetLastCheckResult(void) const
|
||||
{
|
||||
return Get("last_result");
|
||||
return m_LastResult;
|
||||
}
|
||||
|
||||
void Service::SetLastStateChange(double ts)
|
||||
{
|
||||
Set("last_state_change", static_cast<long>(ts));
|
||||
m_LastStateChange = ts;
|
||||
Touch("last_state_change");
|
||||
}
|
||||
|
||||
double Service::GetLastStateChange(void) const
|
||||
{
|
||||
Value value = Get("last_state_change");
|
||||
|
||||
if (value.IsEmpty())
|
||||
if (m_LastStateChange.IsEmpty())
|
||||
return IcingaApplication::GetInstance()->GetStartTime();
|
||||
|
||||
return value;
|
||||
return m_LastStateChange;
|
||||
}
|
||||
|
||||
void Service::SetLastHardStateChange(double ts)
|
||||
{
|
||||
Set("last_hard_state_change", ts);
|
||||
m_LastHardStateChange = ts;
|
||||
Touch("last_hard_state_change");
|
||||
}
|
||||
|
||||
double Service::GetLastHardStateChange(void) const
|
||||
{
|
||||
Value value = Get("last_hard_state_change");
|
||||
if (m_LastHardStateChange.IsEmpty())
|
||||
return IcingaApplication::GetInstance()->GetStartTime();
|
||||
|
||||
if (value.IsEmpty())
|
||||
value = IcingaApplication::GetInstance()->GetStartTime();
|
||||
|
||||
return value;
|
||||
return m_LastHardStateChange;
|
||||
}
|
||||
|
||||
bool Service::GetEnableActiveChecks(void) const
|
||||
{
|
||||
Value value = Get("enable_active_checks");
|
||||
|
||||
if (value.IsEmpty())
|
||||
if (m_EnableActiveChecks.IsEmpty())
|
||||
return true;
|
||||
|
||||
return static_cast<bool>(value);
|
||||
return static_cast<bool>(m_EnableActiveChecks);
|
||||
}
|
||||
|
||||
void Service::SetEnableActiveChecks(bool enabled)
|
||||
{
|
||||
Set("enable_active_checks", enabled ? 1 : 0);
|
||||
m_EnableActiveChecks = enabled ? 1 : 0;
|
||||
Touch("enable_active_checks");
|
||||
}
|
||||
|
||||
bool Service::GetEnablePassiveChecks(void) const
|
||||
{
|
||||
Value value = Get("enable_passive_checks");
|
||||
|
||||
if (value.IsEmpty())
|
||||
if (m_EnablePassiveChecks.IsEmpty())
|
||||
return true;
|
||||
|
||||
return static_cast<bool>(value);
|
||||
return static_cast<bool>(m_EnablePassiveChecks);
|
||||
}
|
||||
|
||||
void Service::SetEnablePassiveChecks(bool enabled)
|
||||
{
|
||||
Set("enable_passive_checks", enabled ? 1 : 0);
|
||||
m_EnablePassiveChecks = enabled ? 1 : 0;
|
||||
Touch("enable_passive_checks");
|
||||
}
|
||||
|
||||
bool Service::GetForceNextCheck(void) const
|
||||
{
|
||||
Value value = Get("force_next_check");
|
||||
|
||||
if (value.IsEmpty())
|
||||
if (m_ForceNextCheck.IsEmpty())
|
||||
return false;
|
||||
|
||||
return static_cast<bool>(value);
|
||||
return static_cast<bool>(m_ForceNextCheck);
|
||||
}
|
||||
|
||||
void Service::SetForceNextCheck(bool forced)
|
||||
{
|
||||
Set("force_next_check", forced ? 1 : 0);
|
||||
m_ForceNextCheck = forced ? 1 : 0;
|
||||
Touch("force_next_check");
|
||||
}
|
||||
|
||||
void Service::ApplyCheckResult(const Dictionary::Ptr& cr)
|
||||
@ -429,7 +391,7 @@ void Service::BeginExecuteCheck(const Service::Ptr& self, const function<void (v
|
||||
ObjectLock slock(self);
|
||||
|
||||
/* don't run another check if there is one pending */
|
||||
if (!self->Get("current_task").IsEmpty()) {
|
||||
if (self->m_CurrentTask) {
|
||||
slock.Unlock();
|
||||
|
||||
/* we need to call the callback anyway */
|
||||
@ -481,7 +443,7 @@ void Service::BeginExecuteCheck(const Service::Ptr& self, const function<void (v
|
||||
{
|
||||
ObjectLock olock(self);
|
||||
task = self->MakeMethodTask("check", arguments);
|
||||
self->Set("current_task", task);
|
||||
self->m_CurrentTask = task;
|
||||
}
|
||||
|
||||
task->Start(boost::bind(&Service::CheckCompletedHandler, self, checkInfo, _1, callback));
|
||||
@ -537,11 +499,11 @@ void Service::CheckCompletedHandler(const Dictionary::Ptr& checkInfo,
|
||||
if (!result->Contains("active"))
|
||||
result->Set("active", 1);
|
||||
|
||||
if (!result->Contains("checker")) {
|
||||
if (!result->Contains("current_checker")) {
|
||||
EndpointManager::Ptr em = EndpointManager::GetInstance();
|
||||
ObjectLock olock(em);
|
||||
|
||||
result->Set("checker", em->GetIdentity());
|
||||
result->Set("current_checker", em->GetIdentity());
|
||||
}
|
||||
}
|
||||
|
||||
@ -550,7 +512,7 @@ void Service::CheckCompletedHandler(const Dictionary::Ptr& checkInfo,
|
||||
if (result)
|
||||
ProcessCheckResult(result);
|
||||
|
||||
Set("current_task", Empty);
|
||||
m_CurrentTask.reset();
|
||||
|
||||
/* figure out when the next check is for this service; the call to
|
||||
* ApplyCheckResult() should've already done this but lets do it again
|
||||
|
@ -34,9 +34,7 @@ int Service::GetNextCommentID(void)
|
||||
|
||||
Dictionary::Ptr Service::GetComments(void) const
|
||||
{
|
||||
Service::ValidateCommentsCache();
|
||||
|
||||
return Get("comments");
|
||||
return m_Comments;
|
||||
}
|
||||
|
||||
String Service::AddComment(CommentType entryType, const String& author,
|
||||
@ -50,14 +48,16 @@ String Service::AddComment(CommentType entryType, const String& author,
|
||||
comment->Set("expire_time", expireTime);
|
||||
comment->Set("legacy_id", m_NextCommentID++);
|
||||
|
||||
Dictionary::Ptr comments = Get("comments");
|
||||
Dictionary::Ptr comments = m_Comments;
|
||||
|
||||
if (!comments)
|
||||
comments = boost::make_shared<Dictionary>();
|
||||
|
||||
String id = Utility::NewUUID();
|
||||
comments->Set(id, comment);
|
||||
Set("comments", comments);
|
||||
|
||||
m_Comments = comments;
|
||||
Touch("comments");
|
||||
|
||||
return id;
|
||||
}
|
||||
@ -74,7 +74,7 @@ void Service::RemoveComment(const String& id)
|
||||
if (!owner)
|
||||
return;
|
||||
|
||||
Dictionary::Ptr comments = owner->Get("comments");
|
||||
Dictionary::Ptr comments = owner->m_Comments;
|
||||
|
||||
if (comments) {
|
||||
comments->Remove(id);
|
||||
@ -106,7 +106,7 @@ Dictionary::Ptr Service::GetCommentByID(const String& id)
|
||||
if (!owner)
|
||||
return Dictionary::Ptr();
|
||||
|
||||
Dictionary::Ptr comments = owner->Get("comments");
|
||||
Dictionary::Ptr comments = owner->m_Comments;
|
||||
|
||||
if (comments) {
|
||||
Dictionary::Ptr comment = comments->Get(id);
|
||||
@ -132,7 +132,7 @@ void Service::InvalidateCommentsCache(void)
|
||||
|
||||
void Service::AddCommentsToCache(void)
|
||||
{
|
||||
Dictionary::Ptr comments = Get("comments");
|
||||
Dictionary::Ptr comments = m_Comments;
|
||||
|
||||
if (!comments)
|
||||
return;
|
||||
@ -184,7 +184,7 @@ void Service::ValidateCommentsCache(void)
|
||||
|
||||
void Service::RemoveExpiredComments(void)
|
||||
{
|
||||
Dictionary::Ptr comments = Get("comments");
|
||||
Dictionary::Ptr comments = m_Comments;
|
||||
|
||||
if (!comments)
|
||||
return;
|
||||
|
@ -34,9 +34,7 @@ int Service::GetNextDowntimeID(void)
|
||||
|
||||
Dictionary::Ptr Service::GetDowntimes(void) const
|
||||
{
|
||||
Service::ValidateDowntimesCache();
|
||||
|
||||
return Get("downtimes");
|
||||
return m_Downtimes;
|
||||
}
|
||||
|
||||
String Service::AddDowntime(const String& author, const String& comment,
|
||||
@ -65,14 +63,16 @@ String Service::AddDowntime(const String& author, const String& comment,
|
||||
otherOwner->Touch("downtimes");
|
||||
}
|
||||
|
||||
Dictionary::Ptr downtimes = Get("downtimes");
|
||||
Dictionary::Ptr downtimes = m_Downtimes;
|
||||
|
||||
if (!downtimes)
|
||||
downtimes = boost::make_shared<Dictionary>();
|
||||
|
||||
String id = Utility::NewUUID();
|
||||
downtimes->Set(id, downtime);
|
||||
Set("downtimes", downtimes);
|
||||
|
||||
m_Downtimes = downtimes;
|
||||
Touch("downtimes");
|
||||
|
||||
return id;
|
||||
}
|
||||
@ -84,7 +84,7 @@ void Service::RemoveDowntime(const String& id)
|
||||
if (!owner)
|
||||
return;
|
||||
|
||||
Dictionary::Ptr downtimes = owner->Get("downtimes");
|
||||
Dictionary::Ptr downtimes = owner->m_Downtimes;
|
||||
|
||||
if (!downtimes)
|
||||
return;
|
||||
@ -95,7 +95,7 @@ void Service::RemoveDowntime(const String& id)
|
||||
|
||||
void Service::TriggerDowntimes(void)
|
||||
{
|
||||
Dictionary::Ptr downtimes = Get("downtimes");
|
||||
Dictionary::Ptr downtimes = m_Downtimes;
|
||||
|
||||
if (!downtimes)
|
||||
return;
|
||||
@ -155,7 +155,7 @@ Dictionary::Ptr Service::GetDowntimeByID(const String& id)
|
||||
if (!owner)
|
||||
return Dictionary::Ptr();
|
||||
|
||||
Dictionary::Ptr downtimes = owner->Get("downtimes");
|
||||
Dictionary::Ptr downtimes = owner->m_Downtimes;
|
||||
|
||||
if (downtimes) {
|
||||
Dictionary::Ptr downtime = downtimes->Get(id);
|
||||
@ -198,7 +198,7 @@ void Service::InvalidateDowntimesCache(void)
|
||||
|
||||
void Service::AddDowntimesToCache(void)
|
||||
{
|
||||
Dictionary::Ptr downtimes = Get("downtimes");
|
||||
Dictionary::Ptr downtimes = m_Downtimes;
|
||||
|
||||
if (!downtimes)
|
||||
return;
|
||||
@ -249,7 +249,7 @@ void Service::ValidateDowntimesCache(void)
|
||||
|
||||
void Service::RemoveExpiredDowntimes(void)
|
||||
{
|
||||
Dictionary::Ptr downtimes = Get("downtimes");
|
||||
Dictionary::Ptr downtimes = m_Downtimes;
|
||||
|
||||
if (!downtimes)
|
||||
return;
|
||||
|
@ -123,38 +123,56 @@ static void CopyNotificationAttributes(TDict notificationDesc, const ConfigItemB
|
||||
builder->AddExpression("notification_interval", OperatorSet, notificationInterval);*/
|
||||
}
|
||||
|
||||
void Service::UpdateSlaveNotifications(void)
|
||||
void Service::UpdateSlaveNotifications(const Service::Ptr& self)
|
||||
{
|
||||
ConfigItem::Ptr item = ConfigItem::GetObject("Service", GetName());
|
||||
Dictionary::Ptr oldNotifications;
|
||||
Host::Ptr host;
|
||||
vector<Dictionary::Ptr> notificationDescsList;
|
||||
String service_name;
|
||||
ConfigItem::Ptr item;
|
||||
|
||||
/* Don't create slave notifications unless we own this object
|
||||
* and it's not a template. */
|
||||
if (!item || IsAbstract())
|
||||
return;
|
||||
{
|
||||
ObjectLock olock(self);
|
||||
|
||||
Dictionary::Ptr oldNotifications = Get("slave_notifications");
|
||||
item = ConfigItem::GetObject("Service", self->GetName());
|
||||
|
||||
/* Don't create slave notifications unless we own this object
|
||||
* and it's not a template. */
|
||||
if (!item || self->IsAbstract())
|
||||
return;
|
||||
|
||||
service_name = self->GetName();
|
||||
oldNotifications = self->m_SlaveNotifications;
|
||||
host = self->GetHost();
|
||||
|
||||
notificationDescsList.push_back(self->Get("notifications"));
|
||||
}
|
||||
|
||||
DebugInfo debug_info;
|
||||
|
||||
{
|
||||
ObjectLock ilock(item);
|
||||
debug_info = item->GetDebugInfo();
|
||||
}
|
||||
|
||||
Dictionary::Ptr newNotifications;
|
||||
newNotifications = boost::make_shared<Dictionary>();
|
||||
|
||||
vector<Dictionary::Ptr> notificationDescsList;
|
||||
|
||||
String host_name;
|
||||
|
||||
{
|
||||
Host::Ptr host = GetHost();
|
||||
ObjectLock olock(host);
|
||||
|
||||
notificationDescsList.push_back(host->Get("notifications"));
|
||||
host_name = host->GetName();
|
||||
}
|
||||
|
||||
notificationDescsList.push_back(Get("notifications"));
|
||||
|
||||
BOOST_FOREACH(const Dictionary::Ptr& notificationDescs, notificationDescsList) {
|
||||
if (!notificationDescs)
|
||||
continue;
|
||||
|
||||
ObjectLock olock(notificationDescs);
|
||||
|
||||
String nfcname;
|
||||
Value nfcdesc;
|
||||
BOOST_FOREACH(tie(nfcname, nfcdesc), notificationDescs) {
|
||||
@ -162,21 +180,22 @@ void Service::UpdateSlaveNotifications(void)
|
||||
nfcname = nfcdesc;
|
||||
|
||||
stringstream namebuf;
|
||||
namebuf << GetName() << "-" << nfcname;
|
||||
namebuf << service_name << "-" << nfcname;
|
||||
String name = namebuf.str();
|
||||
|
||||
ConfigItemBuilder::Ptr builder = boost::make_shared<ConfigItemBuilder>(item->GetDebugInfo());
|
||||
ConfigItemBuilder::Ptr builder = boost::make_shared<ConfigItemBuilder>(debug_info);
|
||||
builder->SetType("Notification");
|
||||
builder->SetName(name);
|
||||
builder->AddExpression("host_name", OperatorSet, host_name);
|
||||
builder->AddExpression("service", OperatorSet, GetName());
|
||||
builder->AddExpression("service", OperatorSet, service_name);
|
||||
|
||||
CopyNotificationAttributes(this, builder);
|
||||
CopyNotificationAttributes(self, builder);
|
||||
|
||||
if (nfcdesc.IsScalar()) {
|
||||
builder->AddParent(nfcdesc);
|
||||
} else if (nfcdesc.IsObjectType<Dictionary>()) {
|
||||
Dictionary::Ptr notification = nfcdesc;
|
||||
ObjectLock nlock(notification);
|
||||
|
||||
Dictionary::Ptr templates = notification->Get("templates");
|
||||
|
||||
@ -212,12 +231,15 @@ void Service::UpdateSlaveNotifications(void)
|
||||
}
|
||||
}
|
||||
|
||||
Set("slave_notifications", newNotifications);
|
||||
{
|
||||
ObjectLock olock(self);
|
||||
self->m_SlaveNotifications = newNotifications;
|
||||
}
|
||||
}
|
||||
|
||||
double Service::GetLastNotification(void) const
|
||||
{
|
||||
Value value = Get("last_notification");
|
||||
Value value = m_LastNotification;
|
||||
|
||||
if (value.IsEmpty())
|
||||
value = 0;
|
||||
@ -227,12 +249,13 @@ double Service::GetLastNotification(void) const
|
||||
|
||||
void Service::SetLastNotification(double time)
|
||||
{
|
||||
Set("last_notification", time);
|
||||
m_LastNotification = time;
|
||||
Touch("last_notification");
|
||||
}
|
||||
|
||||
double Service::GetNextNotification(void) const
|
||||
{
|
||||
Value value = Get("next_notification");
|
||||
Value value = m_NextNotification;
|
||||
|
||||
if (value.IsEmpty())
|
||||
value = 0;
|
||||
@ -242,5 +265,6 @@ double Service::GetNextNotification(void) const
|
||||
|
||||
void Service::SetNextNotification(double time)
|
||||
{
|
||||
Set("next_notification", time);
|
||||
m_NextNotification = time;
|
||||
Touch("next_notification");
|
||||
}
|
||||
|
@ -21,33 +21,51 @@
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
static AttributeDescription serviceAttributes[] = {
|
||||
{ "scheduling_offset", Attribute_Transient },
|
||||
{ "first_check", Attribute_Transient },
|
||||
{ "next_check", Attribute_Replicated },
|
||||
{ "checker", Attribute_Replicated },
|
||||
{ "check_attempt", Attribute_Replicated },
|
||||
{ "state", Attribute_Replicated },
|
||||
{ "state_type", Attribute_Replicated },
|
||||
{ "last_result", Attribute_Replicated },
|
||||
{ "last_state_change", Attribute_Replicated },
|
||||
{ "last_hard_state_change", Attribute_Replicated },
|
||||
{ "enable_active_checks", Attribute_Replicated },
|
||||
{ "enable_passive_checks", Attribute_Replicated },
|
||||
{ "force_next_check", Attribute_Replicated },
|
||||
{ "acknowledgement", Attribute_Replicated },
|
||||
{ "acknowledgement_expiry", Attribute_Replicated },
|
||||
{ "downtimes", Attribute_Replicated },
|
||||
{ "comments", Attribute_Replicated },
|
||||
{ "last_notification", Attribute_Replicated },
|
||||
{ "next_notification", Attribute_Replicated }
|
||||
};
|
||||
|
||||
REGISTER_TYPE(Service, serviceAttributes);
|
||||
REGISTER_TYPE(Service, NULL);
|
||||
|
||||
Service::Service(const Dictionary::Ptr& serializedObject)
|
||||
: DynamicObject(serializedObject)
|
||||
{ }
|
||||
{
|
||||
|
||||
RegisterAttribute("display_name", Attribute_Config, &m_DisplayName);
|
||||
RegisterAttribute("macros", Attribute_Config, &m_Macros);
|
||||
RegisterAttribute("hostdependencies", Attribute_Config, &m_HostDependencies);
|
||||
RegisterAttribute("servicedependencies", Attribute_Config, &m_ServiceDependencies);
|
||||
RegisterAttribute("servicegroups", Attribute_Config, &m_ServiceGroups);
|
||||
|
||||
RegisterAttribute("check_command", Attribute_Config, &m_CheckCommand);
|
||||
RegisterAttribute("max_check_attempts", Attribute_Config, &m_MaxCheckAttempts);
|
||||
RegisterAttribute("check_interval", Attribute_Config, &m_CheckInterval);
|
||||
RegisterAttribute("retry_interval", Attribute_Config, &m_RetryInterval);
|
||||
RegisterAttribute("checkers", Attribute_Config, &m_Checkers);
|
||||
|
||||
RegisterAttribute("next_check", Attribute_Replicated, &m_NextCheck);
|
||||
RegisterAttribute("current_checker", Attribute_Replicated, &m_CurrentChecker);
|
||||
RegisterAttribute("check_attempt", Attribute_Replicated, &m_CheckAttempt);
|
||||
RegisterAttribute("state", Attribute_Replicated, &m_State);
|
||||
RegisterAttribute("state_type", Attribute_Replicated, &m_StateType);
|
||||
RegisterAttribute("last_result", Attribute_Replicated, &m_LastResult);
|
||||
RegisterAttribute("last_state_change", Attribute_Replicated, &m_LastStateChange);
|
||||
RegisterAttribute("last_hard_state_change", Attribute_Replicated, &m_LastHardStateChange);
|
||||
RegisterAttribute("enable_active_checks", Attribute_Replicated, &m_EnableActiveChecks);
|
||||
RegisterAttribute("enable_passive_checks", Attribute_Replicated, &m_EnablePassiveChecks);
|
||||
RegisterAttribute("force_next_check", Attribute_Replicated, &m_ForceNextCheck);
|
||||
|
||||
RegisterAttribute("short_name", Attribute_Config, &m_ShortName);
|
||||
RegisterAttribute("host_name", Attribute_Config, &m_HostName);
|
||||
|
||||
RegisterAttribute("acknowledgement", Attribute_Replicated, &m_Acknowledgement);
|
||||
RegisterAttribute("acknowledgement_expiry", Attribute_Replicated, &m_AcknowledgementExpiry);
|
||||
|
||||
RegisterAttribute("comments", Attribute_Replicated, &m_Comments);
|
||||
|
||||
RegisterAttribute("downtimes", Attribute_Replicated, &m_Downtimes);
|
||||
|
||||
RegisterAttribute("last_notification", Attribute_Replicated, &m_LastNotification);
|
||||
RegisterAttribute("next_notification", Attribute_Replicated, &m_NextNotification);
|
||||
|
||||
SetSchedulingOffset(rand());
|
||||
}
|
||||
|
||||
void Service::OnRegistrationCompleted(void)
|
||||
{
|
||||
@ -60,7 +78,7 @@ void Service::OnRegistrationCompleted(void)
|
||||
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
UpdateSlaveNotifications();
|
||||
m_Host = Host::GetByName(GetHostName());
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,12 +92,10 @@ Service::~Service(void)
|
||||
|
||||
String Service::GetDisplayName(void) const
|
||||
{
|
||||
String value = Get("display_name");
|
||||
|
||||
if (value.IsEmpty())
|
||||
if (m_DisplayName.IsEmpty())
|
||||
return GetShortName();
|
||||
|
||||
return value;
|
||||
else
|
||||
return m_DisplayName;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -119,42 +135,40 @@ Service::Ptr Service::GetByNamePair(const String& hostName, const String& servic
|
||||
|
||||
Host::Ptr Service::GetHost(void) const
|
||||
{
|
||||
String hostname = Get("host_name");
|
||||
|
||||
if (hostname.IsEmpty())
|
||||
BOOST_THROW_EXCEPTION(runtime_error("Service object is missing the 'host_name' property."));
|
||||
|
||||
return Host::GetByName(hostname);
|
||||
return m_Host;
|
||||
}
|
||||
|
||||
Dictionary::Ptr Service::GetMacros(void) const
|
||||
{
|
||||
return Get("macros");
|
||||
return m_Macros;
|
||||
}
|
||||
|
||||
Dictionary::Ptr Service::GetHostDependencies(void) const
|
||||
{
|
||||
return Get("hostdependencies");
|
||||
return m_HostDependencies;
|
||||
}
|
||||
|
||||
Dictionary::Ptr Service::GetServiceDependencies(void) const
|
||||
{
|
||||
return Get("servicedependencies");
|
||||
return m_ServiceDependencies;
|
||||
}
|
||||
|
||||
Dictionary::Ptr Service::GetGroups(void) const
|
||||
{
|
||||
return Get("servicegroups");
|
||||
return m_ServiceGroups;
|
||||
}
|
||||
|
||||
String Service::GetHostName(void) const
|
||||
{
|
||||
return m_HostName;
|
||||
}
|
||||
|
||||
String Service::GetShortName(void) const
|
||||
{
|
||||
Value value = Get("short_name");
|
||||
|
||||
if (value.IsEmpty())
|
||||
if (m_ShortName.IsEmpty())
|
||||
return GetName();
|
||||
|
||||
return value;
|
||||
else
|
||||
return m_ShortName;
|
||||
}
|
||||
|
||||
bool Service::IsReachable(const Service::Ptr& self)
|
||||
@ -212,12 +226,10 @@ bool Service::IsReachable(const Service::Ptr& self)
|
||||
|
||||
AcknowledgementType Service::GetAcknowledgement(void)
|
||||
{
|
||||
Value value = Get("acknowledgement");
|
||||
|
||||
if (value.IsEmpty())
|
||||
if (m_Acknowledgement.IsEmpty())
|
||||
return AcknowledgementNone;
|
||||
|
||||
int ivalue = static_cast<int>(value);
|
||||
int ivalue = static_cast<int>(m_Acknowledgement);
|
||||
AcknowledgementType avalue = static_cast<AcknowledgementType>(ivalue);
|
||||
|
||||
if (avalue != AcknowledgementNone) {
|
||||
@ -235,7 +247,8 @@ AcknowledgementType Service::GetAcknowledgement(void)
|
||||
|
||||
void Service::SetAcknowledgement(AcknowledgementType acknowledgement)
|
||||
{
|
||||
Set("acknowledgement", static_cast<long>(acknowledgement));
|
||||
m_Acknowledgement = acknowledgement;
|
||||
Touch("acknowledgement");
|
||||
}
|
||||
|
||||
bool Service::IsAcknowledged(void)
|
||||
@ -245,17 +258,16 @@ bool Service::IsAcknowledged(void)
|
||||
|
||||
double Service::GetAcknowledgementExpiry(void) const
|
||||
{
|
||||
Value value = Get("acknowledgement_expiry");
|
||||
|
||||
if (value.IsEmpty())
|
||||
if (m_AcknowledgementExpiry.IsEmpty())
|
||||
return 0;
|
||||
|
||||
return static_cast<double>(value);
|
||||
return static_cast<double>(m_AcknowledgementExpiry);
|
||||
}
|
||||
|
||||
void Service::SetAcknowledgementExpiry(double timestamp)
|
||||
{
|
||||
Set("acknowledgement_expiry", timestamp);
|
||||
m_AcknowledgementExpiry = timestamp;
|
||||
Touch("acknowledgement_expiry");
|
||||
}
|
||||
|
||||
void Service::AcknowledgeProblem(AcknowledgementType type, double expiry)
|
||||
@ -274,7 +286,7 @@ void Service::ClearAcknowledgement(void)
|
||||
|
||||
void Service::OnAttributeChanged(const String& name, const Value& oldValue)
|
||||
{
|
||||
if (name == "checker")
|
||||
if (name == "current_checker")
|
||||
OnCheckerChanged(GetSelf(), oldValue);
|
||||
else if (name == "next_check")
|
||||
OnNextCheckChanged(GetSelf(), oldValue);
|
||||
@ -283,16 +295,16 @@ void Service::OnAttributeChanged(const String& name, const Value& oldValue)
|
||||
else if (name == "host_name" || name == "short_name") {
|
||||
Host::InvalidateServicesCache();
|
||||
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
UpdateSlaveNotifications();
|
||||
}
|
||||
UpdateSlaveNotifications(GetSelf());
|
||||
|
||||
if (name == "host_name")
|
||||
m_Host = Host::GetByName(GetHostName());
|
||||
} else if (name == "downtimes")
|
||||
Service::InvalidateDowntimesCache();
|
||||
else if (name == "comments")
|
||||
Service::InvalidateCommentsCache();
|
||||
else if (name == "notifications")
|
||||
UpdateSlaveNotifications();
|
||||
UpdateSlaveNotifications(GetSelf());
|
||||
else if (name == "check_interval") {
|
||||
ObjectLock(this);
|
||||
ConfigItem::Ptr item = ConfigItem::GetObject("Service", GetName());
|
||||
|
@ -104,6 +104,7 @@ public:
|
||||
Dictionary::Ptr GetHostDependencies(void) const;
|
||||
Dictionary::Ptr GetServiceDependencies(void) const;
|
||||
Dictionary::Ptr GetGroups(void) const;
|
||||
String GetHostName(void) const;
|
||||
String GetShortName(void) const;
|
||||
|
||||
static Dictionary::Ptr CalculateDynamicMacros(const Service::Ptr& self);
|
||||
@ -126,15 +127,12 @@ public:
|
||||
long GetSchedulingOffset(void);
|
||||
void SetSchedulingOffset(long offset);
|
||||
|
||||
void SetFirstCheck(bool first);
|
||||
bool GetFirstCheck(void) const;
|
||||
|
||||
void SetNextCheck(double nextCheck);
|
||||
double GetNextCheck(void);
|
||||
void UpdateNextCheck(void);
|
||||
|
||||
void SetChecker(const String& checker);
|
||||
String GetChecker(void) const;
|
||||
void SetCurrentChecker(const String& checker);
|
||||
String GetCurrentChecker(void) const;
|
||||
|
||||
bool IsAllowedChecker(const String& checker) const;
|
||||
|
||||
@ -245,7 +243,7 @@ public:
|
||||
|
||||
set<Notification::Ptr> GetNotifications(void) const;
|
||||
|
||||
void UpdateSlaveNotifications(void);
|
||||
static void UpdateSlaveNotifications(const Service::Ptr& self);
|
||||
|
||||
double GetLastNotification(void) const;
|
||||
void SetLastNotification(double time);
|
||||
@ -258,10 +256,46 @@ protected:
|
||||
virtual void OnAttributeChanged(const String& name, const Value& oldValue);
|
||||
|
||||
private:
|
||||
Host::Ptr m_Host;
|
||||
Dictionary::Ptr m_SlaveNotifications;
|
||||
|
||||
Attribute<String> m_DisplayName;
|
||||
Attribute<Dictionary::Ptr> m_Macros;
|
||||
Attribute<Dictionary::Ptr> m_HostDependencies;
|
||||
Attribute<Dictionary::Ptr> m_ServiceDependencies;
|
||||
Attribute<Dictionary::Ptr> m_ServiceGroups;
|
||||
Attribute<String> m_ShortName;
|
||||
Attribute<long> m_Acknowledgement;
|
||||
Attribute<double> m_AcknowledgementExpiry;
|
||||
Attribute<String> m_HostName;
|
||||
|
||||
/* Checks */
|
||||
Attribute<Value> m_CheckCommand;
|
||||
Attribute<long> m_MaxCheckAttempts;
|
||||
Attribute<double> m_CheckInterval;
|
||||
Attribute<double> m_RetryInterval;
|
||||
Attribute<double> m_NextCheck;
|
||||
Attribute<Dictionary::Ptr> m_Checkers;
|
||||
Attribute<String> m_CurrentChecker;
|
||||
Attribute<long> m_CheckAttempt;
|
||||
Attribute<long> m_State;
|
||||
Attribute<long> m_StateType;
|
||||
Attribute<Dictionary::Ptr> m_LastResult;
|
||||
Attribute<double> m_LastStateChange;
|
||||
Attribute<double> m_LastHardStateChange;
|
||||
Attribute<bool> m_EnableActiveChecks;
|
||||
Attribute<bool> m_EnablePassiveChecks;
|
||||
Attribute<bool> m_ForceNextCheck;
|
||||
|
||||
ScriptTask::Ptr m_CurrentTask;
|
||||
long m_SchedulingOffset;
|
||||
|
||||
void CheckCompletedHandler(const Dictionary::Ptr& checkInfo,
|
||||
const ScriptTask::Ptr& task, const function<void (void)>& callback);
|
||||
|
||||
/* Downtimes */
|
||||
Attribute<Dictionary::Ptr> m_Downtimes;
|
||||
|
||||
static int m_NextDowntimeID;
|
||||
|
||||
static map<int, String> m_LegacyDowntimesCache;
|
||||
@ -275,6 +309,8 @@ private:
|
||||
void RemoveExpiredDowntimes(void);
|
||||
|
||||
/* Comments */
|
||||
Attribute<Dictionary::Ptr> m_Comments;
|
||||
|
||||
static int m_NextCommentID;
|
||||
|
||||
static map<int, String> m_LegacyCommentsCache;
|
||||
@ -288,6 +324,9 @@ private:
|
||||
void RemoveExpiredComments(void);
|
||||
|
||||
/* Notifications */
|
||||
Attribute<double> m_LastNotification;
|
||||
Attribute<double> m_NextNotification;
|
||||
|
||||
static map<String, set<Notification::WeakPtr> > m_NotificationsCache;
|
||||
static bool m_NotificationsCacheValid;
|
||||
};
|
||||
|
@ -29,26 +29,28 @@ REGISTER_TYPE(ServiceGroup, NULL);
|
||||
|
||||
ServiceGroup::ServiceGroup(const Dictionary::Ptr& properties)
|
||||
: DynamicObject(properties)
|
||||
{ }
|
||||
{
|
||||
RegisterAttribute("display_name", Attribute_Config, &m_DisplayName);
|
||||
RegisterAttribute("notes_url", Attribute_Config, &m_NotesUrl);
|
||||
RegisterAttribute("action_url", Attribute_Config, &m_ActionUrl);
|
||||
}
|
||||
|
||||
String ServiceGroup::GetDisplayName(void) const
|
||||
{
|
||||
String value = Get("display_name");
|
||||
|
||||
if (!value.IsEmpty())
|
||||
return value;
|
||||
if (!m_DisplayName.Get().IsEmpty())
|
||||
return m_DisplayName;
|
||||
else
|
||||
return GetName();
|
||||
}
|
||||
|
||||
String ServiceGroup::GetNotesUrl(void) const
|
||||
{
|
||||
return Get("notes_url");
|
||||
return m_NotesUrl;
|
||||
}
|
||||
|
||||
String ServiceGroup::GetActionUrl(void) const
|
||||
{
|
||||
return Get("action_url");
|
||||
return m_ActionUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -47,6 +47,10 @@ public:
|
||||
static void InvalidateMembersCache(void);
|
||||
|
||||
private:
|
||||
Attribute<String> m_DisplayName;
|
||||
Attribute<String> m_NotesUrl;
|
||||
Attribute<String> m_ActionUrl;
|
||||
|
||||
static boost::mutex m_Mutex;
|
||||
static map<String, vector<weak_ptr<Service> > > m_MembersCache;
|
||||
static bool m_MembersCacheValid;
|
||||
|
@ -25,7 +25,9 @@ REGISTER_TYPE(User, NULL);
|
||||
|
||||
User::User(const Dictionary::Ptr& properties)
|
||||
: DynamicObject(properties)
|
||||
{ }
|
||||
{
|
||||
RegisterAttribute("macros", Attribute_Config, &m_Macros);
|
||||
}
|
||||
|
||||
bool User::Exists(const String& name)
|
||||
{
|
||||
@ -44,7 +46,7 @@ User::Ptr User::GetByName(const String& name)
|
||||
|
||||
Dictionary::Ptr User::GetMacros(void) const
|
||||
{
|
||||
return Get("macros");
|
||||
return m_Macros;
|
||||
}
|
||||
|
||||
Dictionary::Ptr User::CalculateDynamicMacros(const User::Ptr& self)
|
||||
|
@ -41,6 +41,9 @@ public:
|
||||
|
||||
Dictionary::Ptr GetMacros(void) const;
|
||||
static Dictionary::Ptr CalculateDynamicMacros(const User::Ptr& self);
|
||||
|
||||
private:
|
||||
Attribute<Dictionary::Ptr> m_Macros;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -21,14 +21,7 @@
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
static AttributeDescription endpointAttributes[] = {
|
||||
{ "node", Attribute_Replicated },
|
||||
{ "service", Attribute_Replicated },
|
||||
{ "subscriptions", Attribute_Replicated },
|
||||
{ "client", Attribute_Transient }
|
||||
};
|
||||
|
||||
REGISTER_TYPE(Endpoint, endpointAttributes);
|
||||
REGISTER_TYPE(Endpoint, NULL);
|
||||
|
||||
signals2::signal<void (const Endpoint::Ptr&)> Endpoint::OnConnected;
|
||||
signals2::signal<void (const Endpoint::Ptr&)> Endpoint::OnDisconnected;
|
||||
@ -42,7 +35,13 @@ signals2::signal<void (const Endpoint::Ptr&, const String& topic)> Endpoint::OnS
|
||||
*/
|
||||
Endpoint::Endpoint(const Dictionary::Ptr& serializedUpdate)
|
||||
: DynamicObject(serializedUpdate)
|
||||
{ }
|
||||
{
|
||||
RegisterAttribute("local", Attribute_Config, &m_Local);
|
||||
|
||||
RegisterAttribute("node", Attribute_Replicated, &m_Node);
|
||||
RegisterAttribute("service", Attribute_Replicated, &m_Service);
|
||||
RegisterAttribute("subscriptions", Attribute_Replicated, &m_Subscriptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether an endpoint with the specified name exists.
|
||||
@ -98,9 +97,7 @@ Endpoint::Ptr Endpoint::MakeEndpoint(const String& name, bool replicated, bool l
|
||||
*/
|
||||
bool Endpoint::IsLocalEndpoint(void) const
|
||||
{
|
||||
Value value = Get("local");
|
||||
|
||||
return (!value.IsEmpty() && value);
|
||||
return m_Local;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -121,12 +118,12 @@ bool Endpoint::IsConnected(void) const
|
||||
|
||||
JsonRpcConnection::Ptr Endpoint::GetClient(void) const
|
||||
{
|
||||
return Get("client");
|
||||
return m_Client;
|
||||
}
|
||||
|
||||
void Endpoint::SetClient(const JsonRpcConnection::Ptr& client)
|
||||
{
|
||||
Set("client", client);
|
||||
m_Client = client;
|
||||
client->OnNewMessage.connect(boost::bind(&Endpoint::NewMessageHandler, this, _2));
|
||||
client->OnClosed.connect(boost::bind(&Endpoint::ClientClosedHandler, this));
|
||||
|
||||
@ -186,17 +183,19 @@ bool Endpoint::HasSubscription(const String& topic) const
|
||||
*/
|
||||
void Endpoint::ClearSubscriptions(void)
|
||||
{
|
||||
Set("subscriptions", Empty);
|
||||
m_Subscriptions = Empty;
|
||||
Touch("subscriptions");
|
||||
}
|
||||
|
||||
Dictionary::Ptr Endpoint::GetSubscriptions(void) const
|
||||
{
|
||||
return Get("subscriptions");
|
||||
return m_Subscriptions;
|
||||
}
|
||||
|
||||
void Endpoint::SetSubscriptions(const Dictionary::Ptr& subscriptions)
|
||||
{
|
||||
Set("subscriptions", subscriptions);
|
||||
m_Subscriptions = subscriptions;
|
||||
Touch("subscriptions");
|
||||
}
|
||||
|
||||
void Endpoint::RegisterTopicHandler(const String& topic, const function<Endpoint::Callback>& callback)
|
||||
@ -336,7 +335,7 @@ void Endpoint::ClientClosedHandler(void)
|
||||
// timer for that, once we have a TTL property for the topics)
|
||||
ClearSubscriptions();
|
||||
|
||||
Set("client", Empty);
|
||||
m_Client.reset();
|
||||
|
||||
OnDisconnected(GetSelf());
|
||||
}
|
||||
@ -348,7 +347,7 @@ void Endpoint::ClientClosedHandler(void)
|
||||
*/
|
||||
String Endpoint::GetNode(void) const
|
||||
{
|
||||
return Get("node");
|
||||
return m_Node;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -358,5 +357,5 @@ String Endpoint::GetNode(void) const
|
||||
*/
|
||||
String Endpoint::GetService(void) const
|
||||
{
|
||||
return Get("service");
|
||||
return m_Service;
|
||||
}
|
||||
|
@ -78,6 +78,13 @@ public:
|
||||
static signals2::signal<void (const Endpoint::Ptr&, const String& topic)> OnSubscriptionUnregistered;
|
||||
|
||||
private:
|
||||
Attribute<bool> m_Local;
|
||||
Attribute<Dictionary::Ptr> m_Subscriptions;
|
||||
Attribute<String> m_Node;
|
||||
Attribute<String> m_Service;
|
||||
|
||||
JsonRpcConnection::Ptr m_Client;
|
||||
|
||||
bool m_ReceivedWelcome; /**< Have we received a welcome message
|
||||
from this endpoint? */
|
||||
bool m_SentWelcome; /**< Have we sent a welcome message to this
|
||||
|
Loading…
x
Reference in New Issue
Block a user