if (checker.IsEmpty())
continue;
- if (!Endpoint::Exists(checker))
- continue;
-
Endpoint::Ptr endpoint = Endpoint::GetByName(checker);
+ if (!endpoint)
+ continue;
+
histogram[endpoint]++;
}
String checker = service->GetCurrentChecker();
- Endpoint::Ptr oldEndpoint;
- if (Endpoint::Exists(checker))
- oldEndpoint = Endpoint::GetByName(checker);
+ Endpoint::Ptr oldEndpoint = Endpoint::GetByName(checker);
set<Endpoint::Ptr> candidates = GetCheckerCandidates(service);
if (service->GetLastNotification() > now - service->GetNotificationInterval())
continue;
- service->RequestNotifications(NotificationProblem);
+ if (Service::IsReachable(service) && !service->IsInDowntime() && !service->IsAcknowledged())
+ service->RequestNotifications(NotificationProblem);
}
}
boost::mutex Host::m_ServiceMutex;
map<String, map<String, weak_ptr<Service> > > Host::m_ServicesCache;
+bool Host::m_ServicesCacheValid = false;
REGISTER_SCRIPTFUNCTION("ValidateServiceDictionary", &Host::ValidateServiceDictionary);
Host::~Host(void)
{
- HostGroup::RefreshMembersCache();
+ HostGroup::InvalidateMembersCache();
if (m_SlaveServices) {
ConfigItem::Ptr service;
{
DynamicObject::OnRegistrationCompleted();
- HostGroup::RefreshMembersCache();
Host::UpdateSlaveServices(GetSelf());
}
return GetName();
}
-/**
- * @threadsafety Always.
- */
-bool Host::Exists(const String& name)
-{
- return (DynamicObject::GetObject("Host", name));
-}
-
/**
* @threadsafety Always.
*/
void Host::OnAttributeChanged(const String& name, const Value&)
{
if (name == "hostgroups")
- HostGroup::RefreshMembersCache();
+ HostGroup::InvalidateMembersCache();
else if (name == "services") {
UpdateSlaveServices(GetSelf());
} else if (name == "notifications") {
return services;
}
+void Host::InvalidateServicesCache(void)
+{
+ {
+ boost::mutex::scoped_lock lock(m_ServiceMutex);
+ m_ServicesCacheValid = false;
+ }
+
+ Utility::QueueAsyncCallback(boost::bind(&Host::RefreshServicesCache));
+}
+
void Host::RefreshServicesCache(void)
{
+ {
+ boost::mutex::scoped_lock lock(m_ServiceMutex);
+
+ if (m_ServicesCacheValid)
+ return;
+
+ m_ServicesCacheValid = true;
+ }
+
map<String, map<String, weak_ptr<Service> > > newServicesCache;
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Service")) {
}
}
- return Service::GetByName(name);
+ return Service::Ptr();
} else if (name.IsObjectType<Dictionary>()) {
Dictionary::Ptr dict = name;
- return GetServiceByShortName(GetByName(dict->Get("host")), dict->Get("service"));
+ String short_name;
+
+ {
+ ObjectLock olock(dict);
+ host_name = dict->Get("host");
+ short_name = dict->Get("service");
+ }
+
+ return Service::GetByNamePair(host_name, short_name);
} else {
BOOST_THROW_EXCEPTION(invalid_argument("Host/Service name pair is invalid."));
}
if (value == host_name)
continue;
- parents.insert(Host::GetByName(value));
+ Host::Ptr host = GetByName(value);
+
+ if (!host)
+ continue;
+
+ parents.insert(host);
}
}
host_check = self->GetHostCheck();
}
+ if (host_check.IsEmpty())
+ return Service::Ptr();
+
return GetServiceByShortName(self, host_check);
}
Host(const Dictionary::Ptr& properties);
~Host(void);
- static bool Exists(const String& name);
static Host::Ptr GetByName(const String& name);
String GetDisplayName(void) const;
static shared_ptr<Service> GetServiceByShortName(const Host::Ptr& self, const Value& name);
set<shared_ptr<Service> > GetServices(void) const;
- static void RefreshServicesCache(void);
+ static void InvalidateServicesCache(void);
static void ValidateServiceDictionary(const ScriptTask::Ptr& task,
const std::vector<icinga::Value>& arguments);
static boost::mutex m_ServiceMutex;
static map<String, map<String, weak_ptr<Service> > > m_ServicesCache;
+ static bool m_ServicesCacheValid;
static void UpdateSlaveServices(const Host::Ptr& self);
- static void ValidateServicesCache(void);
+ static void RefreshServicesCache(void);
};
}
boost::mutex HostGroup::m_Mutex;
map<String, vector<Host::WeakPtr> > HostGroup::m_MembersCache;
+bool HostGroup::m_MembersCacheValid = true;
REGISTER_TYPE(HostGroup, NULL);
HostGroup::~HostGroup(void)
{
- RefreshMembersCache();
+ InvalidateMembersCache();
}
void HostGroup::OnRegistrationCompleted(void)
{
- RefreshMembersCache();
+ InvalidateMembersCache();
}
String HostGroup::GetDisplayName(void) const
return m_ActionUrl;
}
-/**
- * @threadsafety Always.
- */
-bool HostGroup::Exists(const String& name)
-{
- return (DynamicObject::GetObject("HostGroup", name));
-}
-
/**
* @threadsafety Always.
*/
return hosts;
}
+void HostGroup::InvalidateMembersCache(void)
+{
+ {
+ boost::mutex::scoped_lock lock(m_Mutex);
+ m_MembersCacheValid = false;
+ }
+
+ Utility::QueueAsyncCallback(boost::bind(&HostGroup::RefreshMembersCache));
+}
+
void HostGroup::RefreshMembersCache(void)
{
+ {
+ boost::mutex::scoped_lock lock(m_Mutex);
+
+ if (m_MembersCacheValid)
+ return;
+
+ m_MembersCacheValid = true;
+ }
+
map<String, vector<weak_ptr<Host> > > newMembersCache;
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Host")) {
ObjectLock mlock(dict);
Value hostgroup;
BOOST_FOREACH(tie(tuples::ignore, hostgroup), dict) {
- if (!HostGroup::Exists(hostgroup))
- continue;
-
newMembersCache[hostgroup].push_back(host);
}
}
HostGroup(const Dictionary::Ptr& properties);
~HostGroup(void);
- static bool Exists(const String& name);
static HostGroup::Ptr GetByName(const String& name);
String GetDisplayName(void) const;
static set<Host::Ptr> GetMembers(const HostGroup::Ptr& self);
- static void RefreshMembersCache(void);
+ static void InvalidateMembersCache(void);
protected:
virtual void OnRegistrationCompleted(void);
static boost::mutex m_Mutex;
static map<String, vector<weak_ptr<Host> > > m_MembersCache;
+ static bool m_MembersCacheValid;
+
+ static void RefreshMembersCache(void);
};
}
RegisterAttribute("users", Attribute_Config, &m_Users);
RegisterAttribute("host_name", Attribute_Config, &m_HostName);
RegisterAttribute("service", Attribute_Config, &m_Service);
-
- Service::RefreshNotificationsCache();
}
Notification::~Notification(void)
{
- Service::RefreshNotificationsCache();
-}
-
-bool Notification::Exists(const String& name)
-{
- return (DynamicObject::GetObject("Notification", name));
+ Service::InvalidateNotificationsCache();
}
Notification::Ptr Notification::GetByName(const String& name)
{
Host::Ptr host = Host::GetByName(m_HostName);
+ if (!host)
+ return Service::Ptr();
+
if (m_Service.IsEmpty())
return Host::GetHostCheckService(host);
else
void Notification::OnAttributeChanged(const String& name, const Value& oldValue)
{
if (name == "host_name" || name == "service")
- Service::RefreshNotificationsCache();
+ Service::InvalidateNotificationsCache();
}
Notification(const Dictionary::Ptr& properties);
~Notification(void);
- static bool Exists(const String& name);
static Notification::Ptr GetByName(const String& name);
shared_ptr<Service> GetService(void) const;
boost::mutex Service::m_CommentMutex;
map<int, String> Service::m_LegacyCommentsCache;
map<String, Service::WeakPtr> Service::m_CommentsCache;
+bool Service::m_CommentsCacheValid = true;
Timer::Ptr Service::m_CommentsExpireTimer;
int Service::GetNextCommentID(void)
return (expire_time != 0 && expire_time < Utility::GetTime());
}
+void Service::InvalidateCommentsCache(void)
+{
+ {
+ boost::mutex::scoped_lock lock(m_CommentMutex);
+ m_CommentsCacheValid = false;
+ }
+
+ Utility::QueueAsyncCallback(boost::bind(&Service::RefreshCommentsCache));
+}
+
void Service::RefreshCommentsCache(void)
{
+ {
+ boost::mutex::scoped_lock lock(m_CommentMutex);
+
+ if (m_CommentsCacheValid)
+ return;
+
+ m_CommentsCacheValid = true;
+ }
+
map<int, String> newLegacyCommentsCache;
map<String, Service::WeakPtr> newCommentsCache;
boost::mutex Service::m_DowntimeMutex;
map<int, String> Service::m_LegacyDowntimesCache;
map<String, Service::WeakPtr> Service::m_DowntimesCache;
+bool Service::m_DowntimesCacheValid = true;
Timer::Ptr Service::m_DowntimesExpireTimer;
int Service::GetNextDowntimeID(void)
return (downtime->Get("end_time") < Utility::GetTime());
}
+void Service::InvalidateDowntimesCache(void)
+{
+ {
+ boost::mutex::scoped_lock lock(m_DowntimeMutex);
+ m_DowntimesCacheValid = false;
+ }
+
+ Utility::QueueAsyncCallback(boost::bind(&Service::RefreshDowntimesCache));
+}
+
void Service::RefreshDowntimesCache(void)
{
+ {
+ boost::mutex::scoped_lock lock(m_DowntimeMutex);
+
+ if (m_DowntimesCacheValid)
+ return;
+
+ m_DowntimesCacheValid = true;
+ }
+
map<int, String> newLegacyDowntimesCache;
map<String, Service::WeakPtr> newDowntimesCache;
boost::mutex Service::m_NotificationMutex;
map<String, set<Notification::WeakPtr> > Service::m_NotificationsCache;
+bool Service::m_NotificationsCacheValid = true;
void Service::RequestNotifications(NotificationType type)
{
}
}
+void Service::InvalidateNotificationsCache(void)
+{
+ {
+ boost::mutex::scoped_lock lock(m_NotificationMutex);
+ m_NotificationsCacheValid = false;
+ }
+
+ Utility::QueueAsyncCallback(boost::bind(&Service::RefreshNotificationsCache));
+}
+
void Service::RefreshNotificationsCache(void)
{
+ {
+ boost::mutex::scoped_lock lock(m_NotificationMutex);
+
+ if (m_NotificationsCacheValid)
+ return;
+
+ m_NotificationsCacheValid = true;
+ }
+
map<String, set<Notification::WeakPtr> > newNotificationsCache;
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Notification")) {
Dictionary::Ptr oldNotifications;
Host::Ptr host;
vector<Dictionary::Ptr> notificationDescsList;
- String service_name;
+ String service_name, short_name;
ConfigItem::Ptr item;
{
return;
service_name = self->GetName();
+ short_name = self->GetShortName();
oldNotifications = self->m_SlaveNotifications;
host = self->GetHost();
builder->SetType("Notification");
builder->SetName(name);
builder->AddExpression("host_name", OperatorSet, host_name);
- builder->AddExpression("service", OperatorSet, service_name);
+ builder->AddExpression("service", OperatorSet, short_name);
CopyNotificationAttributes(self, builder);
Service::~Service(void)
{
- ServiceGroup::RefreshMembersCache();
- Host::RefreshServicesCache();
- Service::RefreshDowntimesCache();
- Service::RefreshCommentsCache();
+ ServiceGroup::InvalidateMembersCache();
+ Host::InvalidateServicesCache();
+ Service::InvalidateDowntimesCache();
+ Service::InvalidateCommentsCache();
}
void Service::OnRegistrationCompleted(void)
{
DynamicObject::OnRegistrationCompleted();
- ServiceGroup::RefreshMembersCache();
- Host::RefreshServicesCache();
+ Host::InvalidateServicesCache();
}
String Service::GetDisplayName(void) const
return m_DisplayName;
}
-/**
- * @threadsafety Always.
- */
-bool Service::Exists(const String& name)
-{
- return (DynamicObject::GetObject("Service", name));
-}
-
/**
* @threadsafety Always.
*/
{
if (!hostName.IsEmpty()) {
Host::Ptr host = Host::GetByName(hostName);
+
+ if (!host)
+ return Service::Ptr();
+
return Host::GetServiceByShortName(host, serviceName);
} else {
return Service::GetByName(serviceName);
else if (name == "next_check")
OnNextCheckChanged(GetSelf(), oldValue);
else if (name == "servicegroups")
- ServiceGroup::RefreshMembersCache();
+ ServiceGroup::InvalidateMembersCache();
else if (name == "host_name" || name == "short_name") {
- Host::RefreshServicesCache();
+ Host::InvalidateServicesCache();
UpdateSlaveNotifications(GetSelf());
} else if (name == "downtimes")
- Service::RefreshDowntimesCache();
+ Service::InvalidateDowntimesCache();
else if (name == "comments")
- Service::RefreshCommentsCache();
+ Service::InvalidateCommentsCache();
else if (name == "notifications")
UpdateSlaveNotifications(GetSelf());
else if (name == "check_interval") {
if (dependencies) {
String key;
BOOST_FOREACH(tie(key, tuples::ignore), dependencies) {
- parents.insert(Host::GetByName(key));
+ Host::Ptr host = Host::GetByName(key);
+
+ if (!host)
+ continue;
+
+ parents.insert(host);
}
}
Service(const Dictionary::Ptr& properties);
~Service(void);
- static bool Exists(const String& name);
static Service::Ptr GetByName(const String& name);
static Service::Ptr GetByNamePair(const String& hostName, const String& serviceName);
static set<Host::Ptr> GetParentHosts(const Service::Ptr& self);
static set<Service::Ptr> GetParentServices(const Service::Ptr& self);
- bool IsReachable(const Service::Ptr& self);
+ static bool IsReachable(const Service::Ptr& self);
AcknowledgementType GetAcknowledgement(void);
void SetAcknowledgement(AcknowledgementType acknowledgement);
static bool IsDowntimeActive(const Dictionary::Ptr& downtime);
static bool IsDowntimeExpired(const Dictionary::Ptr& downtime);
- static void RefreshDowntimesCache(void);
+ static void InvalidateDowntimesCache(void);
bool IsInDowntime(void) const;
bool IsAcknowledged(void);
static bool IsCommentExpired(const Dictionary::Ptr& comment);
- static void RefreshCommentsCache(void);
+ static void InvalidateCommentsCache(void);
/* Notifications */
bool GetEnableNotifications(void) const;
static set<Notification::Ptr> GetNotifications(const Service::Ptr& self);
- static void RefreshNotificationsCache(void);
+ static void InvalidateNotificationsCache(void);
static void UpdateSlaveNotifications(const Service::Ptr& self);
static boost::mutex m_DowntimeMutex;
static map<int, String> m_LegacyDowntimesCache;
static map<String, Service::WeakPtr> m_DowntimesCache;
+ static bool m_DowntimesCacheValid;
static Timer::Ptr m_DowntimesExpireTimer;
static void DowntimesExpireTimerHandler(void);
void RemoveExpiredDowntimes(void);
+ static void RefreshDowntimesCache(void);
+
/* Comments */
Attribute<Dictionary::Ptr> m_Comments;
static boost::mutex m_CommentMutex;
static map<int, String> m_LegacyCommentsCache;
static map<String, Service::WeakPtr> m_CommentsCache;
+ static bool m_CommentsCacheValid;
static Timer::Ptr m_CommentsExpireTimer;
static void CommentsExpireTimerHandler(void);
void AddCommentsToCache(void);
void RemoveExpiredComments(void);
+ static void RefreshCommentsCache(void);
+
/* Notifications */
Attribute<bool> m_EnableNotifications;
Attribute<double> m_LastNotification;
static boost::mutex m_NotificationMutex;
static map<String, set<Notification::WeakPtr> > m_NotificationsCache;
+ static bool m_NotificationsCacheValid;
+
+ static void RefreshNotificationsCache(void);
};
}
boost::mutex ServiceGroup::m_Mutex;
map<String, vector<Service::WeakPtr> > ServiceGroup::m_MembersCache;
+bool ServiceGroup::m_MembersCacheValid = true;
REGISTER_TYPE(ServiceGroup, NULL);
return m_ActionUrl;
}
-/**
- * @threadsafety Always.
- */
-bool ServiceGroup::Exists(const String& name)
-{
- return (DynamicObject::GetObject("ServiceGroup", name));
-}
-
/**
* @threadsafety Always.
*/
return services;
}
+void ServiceGroup::InvalidateMembersCache(void)
+{
+ {
+ boost::mutex::scoped_lock lock(m_Mutex);
+ m_MembersCacheValid = false;
+ }
+
+ Utility::QueueAsyncCallback(boost::bind(&ServiceGroup::RefreshMembersCache));
+}
+
void ServiceGroup::RefreshMembersCache(void)
{
+ {
+ boost::mutex::scoped_lock lock(m_Mutex);
+
+ if (m_MembersCacheValid)
+ return;
+
+ m_MembersCacheValid = true;
+ }
+
map<String, vector<weak_ptr<Service> > > newMembersCache;
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Service")) {
ObjectLock mlock(dict);
Value servicegroup;
BOOST_FOREACH(tie(tuples::ignore, servicegroup), dict) {
- if (!ServiceGroup::Exists(servicegroup))
- continue;
-
newMembersCache[servicegroup].push_back(service);
}
}
boost::mutex::scoped_lock lock(m_Mutex);
m_MembersCache.swap(newMembersCache);
-
}
ServiceGroup(const Dictionary::Ptr& properties);
~ServiceGroup(void);
- static bool Exists(const String& name);
static ServiceGroup::Ptr GetByName(const String& name);
String GetDisplayName(void) const;
static set<Service::Ptr> GetMembers(const ServiceGroup::Ptr& self);
- static void RefreshMembersCache(void);
+ static void InvalidateMembersCache(void);
protected:
virtual void OnRegistrationCompleted(void);
static boost::mutex m_Mutex;
static map<String, vector<weak_ptr<Service> > > m_MembersCache;
+ static bool m_MembersCacheValid;
+
+ static void RefreshMembersCache(void);
};
}
RegisterAttribute("macros", Attribute_Config, &m_Macros);
}
-bool User::Exists(const String& name)
-{
- return (DynamicObject::GetObject("User", name));
-}
-
User::Ptr User::GetByName(const String& name)
{
DynamicObject::Ptr configObject = DynamicObject::GetObject("User", name);
User(const Dictionary::Ptr& properties);
- static bool Exists(const String& name);
static User::Ptr GetByName(const String& name);
Dictionary::Ptr GetMacros(void) const;
RegisterAttribute("subscriptions", Attribute_Replicated, &m_Subscriptions);
}
-/**
- * Checks whether an endpoint with the specified name exists.
- *
- * @param name The name of the endpoint.
- * @returns true if the endpoint exists, false otherwise.
- */
-bool Endpoint::Exists(const String& name)
-{
- return (DynamicObject::GetObject("Endpoint", name));
-}
-
/**
* Retrieves an endpoint by name.
*
{
DynamicObject::Ptr configObject = DynamicObject::GetObject("Endpoint", name);
- if (!configObject)
- BOOST_THROW_EXCEPTION(invalid_argument("Endpoint '" + name + "' does not exist."));
-
return dynamic_pointer_cast<Endpoint>(configObject);
}
Endpoint(const Dictionary::Ptr& serializedUpdate);
- static bool Exists(const String& name);
static Endpoint::Ptr GetByName(const String& name);
JsonRpcConnection::Ptr GetClient(void) const;
Logger::Write(LogInformation, "icinga", "New client connection at " + peerAddress + " for identity '" + identity + "'");
- Endpoint::Ptr endpoint;
+ Endpoint::Ptr endpoint = Endpoint::GetByName(identity);
- if (Endpoint::Exists(identity))
- endpoint = Endpoint::GetByName(identity);
- else
+ if (!endpoint)
endpoint = Endpoint::MakeEndpoint(identity, true);
endpoint->SetClient(jclient);