Use Expression::Extract* for notifications.

This commit is contained in:
Gunnar Beutner 2013-03-19 14:47:19 +01:00
parent 45e24e4729
commit 711a8cb5e0
7 changed files with 71 additions and 98 deletions

View File

@ -215,7 +215,7 @@ void Expression::Dump(std::ostream& fp, int indent) const
fp << ", " << "\n";
}
void Expression::Extract(const std::vector<String>& path, const ExpressionList::Ptr& result) const
void Expression::ExtractPath(const std::vector<String>& path, const ExpressionList::Ptr& result) const
{
ASSERT(!path.empty());
@ -232,9 +232,19 @@ void Expression::Extract(const std::vector<String>& path, const ExpressionList::
}
std::vector<String> sub_path(path.begin() + 1, path.end());
exprl->Extract(sub_path, result);
exprl->ExtractPath(sub_path, result);
} else if (m_Operator == OperatorExecute) {
ExpressionList::Ptr exprl = m_Value;
exprl->Extract(path, result);
exprl->ExtractPath(path, result);
}
}
void Expression::ExtractFiltered(const std::set<String, string_iless>& keys, const shared_ptr<ExpressionList>& result) const
{
if (keys.find(m_Key) != keys.end()) {
result->AddExpression(*this);
} else if (m_Operator == OperatorExecute) {
ExpressionList::Ptr exprl = m_Value;
exprl->ExtractFiltered(keys, result);
}
}

View File

@ -25,6 +25,7 @@
#include "base/dictionary.h"
#include <iostream>
#include <vector>
#include <set>
namespace icinga
{
@ -60,7 +61,8 @@ public:
void Execute(const Dictionary::Ptr& dictionary) const;
void Dump(std::ostream& fp, int indent = 0) const;
void Extract(const std::vector<String>& path, const shared_ptr<ExpressionList>& result) const;
void ExtractPath(const std::vector<String>& path, const shared_ptr<ExpressionList>& result) const;
void ExtractFiltered(const std::set<String, string_iless>& keys, const shared_ptr<ExpressionList>& result) const;
private:
String m_Key;

View File

@ -68,9 +68,16 @@ void ExpressionList::Dump(std::ostream& fp, int indent) const
}
}
void ExpressionList::Extract(const std::vector<String>& path, const ExpressionList::Ptr& result) const
void ExpressionList::ExtractPath(const std::vector<String>& path, const ExpressionList::Ptr& result) const
{
BOOST_FOREACH(const Expression& expression, m_Expressions) {
expression.Extract(path, result);
}
expression.ExtractPath(path, result);
}
}
void ExpressionList::ExtractFiltered(const std::set<String, string_iless>& keys, const ExpressionList::Ptr& result) const
{
BOOST_FOREACH(const Expression& expression, m_Expressions) {
expression.ExtractFiltered(keys, result);
}
}

View File

@ -46,7 +46,8 @@ public:
size_t GetLength(void) const;
void Extract(const std::vector<String>& path, const ExpressionList::Ptr& result) const;
void ExtractPath(const std::vector<String>& path, const ExpressionList::Ptr& result) const;
void ExtractFiltered(const std::set<String, string_iless>& keys, const ExpressionList::Ptr& result) const;
private:
std::vector<Expression> m_Expressions;

View File

@ -168,55 +168,6 @@ bool Host::IsReachable(void) const
return true;
}
template<bool copyServiceAttrs, typename TDict>
static void CopyServiceAttributes(TDict serviceDesc, const ConfigItemBuilder::Ptr& builder)
{
/* TODO: we only need to copy macros if this is an inline definition,
* i.e. "typeid(serviceDesc)" != Service, however for now we just
* copy them anyway. */
Value macros = serviceDesc->Get("macros");
if (!macros.IsEmpty())
builder->AddExpression("macros", OperatorPlus, macros);
Value checkInterval = serviceDesc->Get("check_interval");
if (!checkInterval.IsEmpty())
builder->AddExpression("check_interval", OperatorSet, checkInterval);
Value retryInterval = serviceDesc->Get("retry_interval");
if (!retryInterval.IsEmpty())
builder->AddExpression("retry_interval", OperatorSet, retryInterval);
Value sgroups = serviceDesc->Get("servicegroups");
if (!sgroups.IsEmpty())
builder->AddExpression("servicegroups", OperatorPlus, sgroups);
Value checkers = serviceDesc->Get("checkers");
if (!checkers.IsEmpty())
builder->AddExpression("checkers", OperatorSet, checkers);
Value short_name = serviceDesc->Get("short_name");
if (!short_name.IsEmpty())
builder->AddExpression("short_name", OperatorSet, short_name);
Value notification_interval = serviceDesc->Get("notification_interval");
if (!notification_interval.IsEmpty())
builder->AddExpression("notification_interval", OperatorSet, notification_interval);
Value check_period = serviceDesc->Get("check_period");
if (!check_period.IsEmpty())
builder->AddExpression("check_period", OperatorSet, check_period);
if (copyServiceAttrs) {
Value servicedependencies = serviceDesc->Get("servicedependencies");
if (!servicedependencies.IsEmpty())
builder->AddExpression("servicedependencies", OperatorPlus, servicedependencies);
Value hostdependencies = serviceDesc->Get("hostdependencies");
if (!hostdependencies.IsEmpty())
builder->AddExpression("hostdependencies", OperatorPlus, hostdependencies);
}
}
void Host::UpdateSlaveServices(void)
{
ASSERT(!OwnsLock());
@ -251,18 +202,8 @@ void Host::UpdateSlaveServices(void)
builder->AddExpression("display_name", OperatorSet, svcname);
builder->AddExpression("short_name", OperatorSet, svcname);
std::vector<String> path;
path.push_back("services");
path.push_back(svcname);
ExpressionList::Ptr exprl = boost::make_shared<ExpressionList>();
item->GetLinkedExpressionList()->Extract(path, exprl);
builder->AddExpressionList(exprl);
/*CopyServiceAttributes<false>(this, builder);
if (!svcdesc.IsObjectType<Dictionary>())
BOOST_THROW_EXCEPTION(std::invalid_argument("Service description must be either a string or a dictionary."));*/
BOOST_THROW_EXCEPTION(std::invalid_argument("Service description must be either a string or a dictionary."));
Dictionary::Ptr service = svcdesc;
@ -276,7 +217,29 @@ void Host::UpdateSlaveServices(void)
}
}
//CopyServiceAttributes<true>(service, builder);
/* Clone attributes from the host object. */
std::set<String, string_iless> keys;
keys.insert("check_interval");
keys.insert("retry_interval");
keys.insert("servicegroups");
keys.insert("checkers");
keys.insert("notification_interval");
keys.insert("check_period");
keys.insert("servicedependencies");
keys.insert("hostdependencies");
ExpressionList::Ptr host_exprl = boost::make_shared<ExpressionList>();
item->GetLinkedExpressionList()->ExtractFiltered(keys, host_exprl);
builder->AddExpressionList(host_exprl);
/* Clone attributes from the service expression list. */
std::vector<String> path;
path.push_back("services");
path.push_back(svcname);
ExpressionList::Ptr svc_exprl = boost::make_shared<ExpressionList>();
item->GetLinkedExpressionList()->ExtractPath(path, svc_exprl);
builder->AddExpressionList(svc_exprl);
ConfigItem::Ptr serviceItem = builder->Compile();
DynamicObject::Ptr dobj = serviceItem->Commit();

View File

@ -44,6 +44,7 @@ type Host {
},
%attribute string "short_name",
%attribute string "display_name",
%attribute dictionary "macros" {
%attribute string "*"

View File

@ -167,32 +167,6 @@ std::set<Notification::Ptr> Service::GetNotifications(void) const
return notifications;
}
/**
* @threadsafety Always.
*/
template<typename TDict>
static void CopyNotificationAttributes(TDict notificationDesc, const ConfigItemBuilder::Ptr& builder)
{
/* TODO: we only need to copy macros if this is an inline definition,
* i.e. "typeid(notificationDesc)" != Notification, however for now we just
* copy them anyway. */
Value macros = notificationDesc->Get("macros");
if (!macros.IsEmpty())
builder->AddExpression("macros", OperatorPlus, macros);
Value users = notificationDesc->Get("users");
if (!users.IsEmpty())
builder->AddExpression("users", OperatorPlus, users);
Value groups = notificationDesc->Get("groups");
if (!groups.IsEmpty())
builder->AddExpression("groups", OperatorPlus, groups);
/*Value notificationInterval = notificationDesc->Get("notification_interval");
if (!notificationInterval.IsEmpty())
builder->AddExpression("notification_interval", OperatorSet, notificationInterval);*/
}
void Service::UpdateSlaveNotifications(void)
{
Dictionary::Ptr oldNotifications;
@ -241,8 +215,6 @@ void Service::UpdateSlaveNotifications(void)
builder->AddExpression("host_name", OperatorSet, host->GetName());
builder->AddExpression("service", OperatorSet, GetShortName());
CopyNotificationAttributes(this, builder);
if (!nfcdesc.IsObjectType<Dictionary>())
BOOST_THROW_EXCEPTION(std::invalid_argument("Notification description must be a dictionary."));
@ -258,7 +230,24 @@ void Service::UpdateSlaveNotifications(void)
}
}
CopyNotificationAttributes(notification, builder);
/* Clone attributes from the service object. */
std::set<String, string_iless> keys;
keys.insert("users");
keys.insert("groups");
keys.insert("notification_interval");
ExpressionList::Ptr svc_exprl = boost::make_shared<ExpressionList>();
item->GetLinkedExpressionList()->ExtractFiltered(keys, svc_exprl);
builder->AddExpressionList(svc_exprl);
/* Clone attributes from the notification expression list. */
std::vector<String> path;
path.push_back("notifications");
path.push_back(nfcname);
ExpressionList::Ptr nfc_exprl = boost::make_shared<ExpressionList>();
item->GetLinkedExpressionList()->ExtractPath(path, nfc_exprl);
builder->AddExpressionList(nfc_exprl);
ConfigItem::Ptr notificationItem = builder->Compile();
notificationItem->Commit();