Implement support for arrays in custom variables

fixes #6544
This commit is contained in:
Gunnar Beutner 2014-11-02 07:22:00 +01:00
parent 9844a2c990
commit 4677014b6d
13 changed files with 368 additions and 176 deletions

View File

@ -25,12 +25,14 @@
#include "base/socket.hpp" #include "base/socket.hpp"
#include "base/utility.hpp" #include "base/utility.hpp"
#include "base/json.hpp" #include "base/json.hpp"
#include "base/objectlock.hpp"
#include <mmatch.h> #include <mmatch.h>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/algorithm/string/split.hpp> #include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp> #include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/trim.hpp> #include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <ios> #include <ios>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
@ -772,6 +774,35 @@ String Utility::NaturalJoin(const std::vector<String>& tokens)
return result; return result;
} }
String Utility::Join(const Array::Ptr& tokens, char separator)
{
String result;
bool first = true;
ObjectLock olock(tokens);
BOOST_FOREACH(const Value& vtoken, tokens) {
String token = Convert::ToString(vtoken);
boost::algorithm::replace_all(token, "\\", "\\\\");
char sep_before[2], sep_after[3];
sep_before[0] = separator;
sep_before[1] = '\0';
sep_after[0] = '\\';
sep_after[1] = separator;
sep_after[2] = '\0';
boost::algorithm::replace_all(token, sep_before, sep_after);
if (first)
first = false;
else
result += String(1, separator);
result += token;
}
return result;
}
String Utility::FormatDuration(double duration) String Utility::FormatDuration(double duration)
{ {
std::vector<String> tokens; std::vector<String> tokens;

View File

@ -22,6 +22,7 @@
#include "base/i2-base.hpp" #include "base/i2-base.hpp"
#include "base/string.hpp" #include "base/string.hpp"
#include "base/array.hpp"
#include <typeinfo> #include <typeinfo>
#include <boost/function.hpp> #include <boost/function.hpp>
#include <boost/thread/tss.hpp> #include <boost/thread/tss.hpp>
@ -96,6 +97,7 @@ public:
static void QueueAsyncCallback(const boost::function<void (void)>& callback, SchedulerPolicy policy = DefaultScheduler); static void QueueAsyncCallback(const boost::function<void (void)>& callback, SchedulerPolicy policy = DefaultScheduler);
static String NaturalJoin(const std::vector<String>& tokens); static String NaturalJoin(const std::vector<String>& tokens);
static String Join(const Array::Ptr& tokens, char separator);
static String FormatDuration(double duration); static String FormatDuration(double duration);
static String FormatDateTime(const char *format, double ts); static String FormatDateTime(const char *format, double ts);

View File

@ -516,14 +516,22 @@ void StatusDataWriter::DumpCustomAttributes(std::ostream& fp, const CustomVarObj
ObjectLock olock(vars); ObjectLock olock(vars);
BOOST_FOREACH(const Dictionary::Pair& kv, vars) { BOOST_FOREACH(const Dictionary::Pair& kv, vars) {
if (!kv.first.IsEmpty()) { if (kv.first.IsEmpty())
continue;
String value;
if (kv.second.IsObjectType<Array>())
value = Utility::Join(kv.second, ';');
else
value = kv.second;
fp << "\t"; fp << "\t";
if (!CompatUtility::IsLegacyAttribute(object, kv.first)) if (!CompatUtility::IsLegacyAttribute(object, kv.first))
fp << "_"; fp << "_";
fp << kv.first << "\t" << kv.second << "\n"; fp << kv.first << "\t" << value << "\n";
}
} }
} }

View File

@ -28,8 +28,10 @@ ApplyRule::RuleMap ApplyRule::m_Rules;
ApplyRule::CallbackMap ApplyRule::m_Callbacks; ApplyRule::CallbackMap ApplyRule::m_Callbacks;
ApplyRule::ApplyRule(const String& targetType, const String& name, const Expression::Ptr& expression, ApplyRule::ApplyRule(const String& targetType, const String& name, const Expression::Ptr& expression,
const Expression::Ptr& filter, const DebugInfo& di, const Dictionary::Ptr& scope) const Expression::Ptr& filter, const String& fvar, const Expression::Ptr& fterm,
: m_TargetType(targetType), m_Name(name), m_Expression(expression), m_Filter(filter), m_DebugInfo(di), m_Scope(scope) const DebugInfo& di, const Dictionary::Ptr& scope)
: m_TargetType(targetType), m_Name(name), m_Expression(expression), m_Filter(filter), m_FVar(fvar),
m_FTerm(fterm), m_DebugInfo(di), m_Scope(scope)
{ } { }
String ApplyRule::GetTargetType(void) const String ApplyRule::GetTargetType(void) const
@ -52,6 +54,16 @@ Expression::Ptr ApplyRule::GetFilter(void) const
return m_Filter; return m_Filter;
} }
String ApplyRule::GetFVar(void) const
{
return m_FVar;
}
Expression::Ptr ApplyRule::GetFTerm(void) const
{
return m_FTerm;
}
DebugInfo ApplyRule::GetDebugInfo(void) const DebugInfo ApplyRule::GetDebugInfo(void) const
{ {
return m_DebugInfo; return m_DebugInfo;
@ -63,10 +75,10 @@ Dictionary::Ptr ApplyRule::GetScope(void) const
} }
void ApplyRule::AddRule(const String& sourceType, const String& targetType, const String& name, void ApplyRule::AddRule(const String& sourceType, const String& targetType, const String& name,
const Expression::Ptr& expression, const Expression::Ptr& filter, const Expression::Ptr& expression, const Expression::Ptr& filter, const String& fvar,
const DebugInfo& di, const Dictionary::Ptr& scope) const Expression::Ptr& fterm, const DebugInfo& di, const Dictionary::Ptr& scope)
{ {
m_Rules[sourceType].push_back(ApplyRule(targetType, name, expression, filter, di, scope)); m_Rules[sourceType].push_back(ApplyRule(targetType, name, expression, filter, fvar, fterm, di, scope));
} }
bool ApplyRule::EvaluateFilter(const Dictionary::Ptr& scope) const bool ApplyRule::EvaluateFilter(const Dictionary::Ptr& scope) const

View File

@ -42,13 +42,15 @@ public:
String GetName(void) const; String GetName(void) const;
Expression::Ptr GetExpression(void) const; Expression::Ptr GetExpression(void) const;
Expression::Ptr GetFilter(void) const; Expression::Ptr GetFilter(void) const;
String GetFVar(void) const;
Expression::Ptr GetFTerm(void) const;
DebugInfo GetDebugInfo(void) const; DebugInfo GetDebugInfo(void) const;
Dictionary::Ptr GetScope(void) const; Dictionary::Ptr GetScope(void) const;
bool EvaluateFilter(const Dictionary::Ptr& scope) const; bool EvaluateFilter(const Dictionary::Ptr& scope) const;
static void AddRule(const String& sourceType, const String& targetType, const String& name, const Expression::Ptr& expression, static void AddRule(const String& sourceType, const String& targetType, const String& name, const Expression::Ptr& expression,
const Expression::Ptr& filter, const DebugInfo& di, const Dictionary::Ptr& scope); const Expression::Ptr& filter, const String& fvar, const Expression::Ptr& fterm, const DebugInfo& di, const Dictionary::Ptr& scope);
static void EvaluateRules(bool clear); static void EvaluateRules(bool clear);
static void RegisterType(const String& sourceType, const std::vector<String>& targetTypes, const ApplyRule::Callback& callback); static void RegisterType(const String& sourceType, const std::vector<String>& targetTypes, const ApplyRule::Callback& callback);
@ -61,6 +63,8 @@ private:
String m_Name; String m_Name;
Expression::Ptr m_Expression; Expression::Ptr m_Expression;
Expression::Ptr m_Filter; Expression::Ptr m_Filter;
String m_FVar;
Expression::Ptr m_FTerm;
DebugInfo m_DebugInfo; DebugInfo m_DebugInfo;
Dictionary::Ptr m_Scope; Dictionary::Ptr m_Scope;
@ -68,7 +72,8 @@ private:
static RuleMap m_Rules; static RuleMap m_Rules;
ApplyRule(const String& targetType, const String& name, const Expression::Ptr& expression, ApplyRule(const String& targetType, const String& name, const Expression::Ptr& expression,
const Expression::Ptr& filter, const DebugInfo& di, const Dictionary::Ptr& scope); const Expression::Ptr& filter, const String& fvar, const Expression::Ptr& fterm,
const DebugInfo& di, const Dictionary::Ptr& scope);
}; };
} }

View File

@ -33,7 +33,10 @@
%attribute %dictionary "methods", %attribute %dictionary "methods",
%attribute %dictionary "vars" { %attribute %dictionary "vars" {
%attribute %string "*",
%attribute %array "*" {
%attribute %string "*" %attribute %string "*"
}
}, },
} }

View File

@ -218,6 +218,8 @@ static std::stack<bool> m_ObjectAssign;
static std::stack<bool> m_SeenAssign; static std::stack<bool> m_SeenAssign;
static std::stack<Expression::Ptr> m_Assign; static std::stack<Expression::Ptr> m_Assign;
static std::stack<Expression::Ptr> m_Ignore; static std::stack<Expression::Ptr> m_Ignore;
static std::stack<String> m_FVar;
static std::stack<Expression::Ptr> m_FTerm;
void ConfigCompiler::Compile(void) void ConfigCompiler::Compile(void)
{ {
@ -231,6 +233,8 @@ void ConfigCompiler::Compile(void)
m_SeenAssign = std::stack<bool>(); m_SeenAssign = std::stack<bool>();
m_Assign = std::stack<Expression::Ptr>(); m_Assign = std::stack<Expression::Ptr>();
m_Ignore = std::stack<Expression::Ptr>(); m_Ignore = std::stack<Expression::Ptr>();
m_FVar = std::stack<String>();
m_FTerm = std::stack<Expression::Ptr>();
try { try {
yyparse(this); yyparse(this);
@ -836,14 +840,27 @@ target_type_specifier: /* empty */
} }
; ;
apply_for_specifier: /* empty */
| T_FOR '(' identifier T_IN rterm ')'
{
m_FVar.top() = $3;
free($3);
m_FTerm.top() = *$5;
delete $5;
}
;
apply: apply:
{ {
m_Apply.push(true); m_Apply.push(true);
m_SeenAssign.push(false); m_SeenAssign.push(false);
m_Assign.push(make_shared<Expression>(&Expression::OpLiteral, false, DebugInfo())); m_Assign.push(make_shared<Expression>(&Expression::OpLiteral, false, DebugInfo()));
m_Ignore.push(make_shared<Expression>(&Expression::OpLiteral, false, DebugInfo())); m_Ignore.push(make_shared<Expression>(&Expression::OpLiteral, false, DebugInfo()));
m_FVar.push("");
m_FTerm.push(Expression::Ptr());
} }
T_APPLY identifier rterm target_type_specifier rterm T_APPLY identifier rterm apply_for_specifier target_type_specifier rterm
{ {
m_Apply.pop(); m_Apply.pop();
@ -851,8 +868,8 @@ apply:
free($3); free($3);
Expression::Ptr aname = *$4; Expression::Ptr aname = *$4;
delete $4; delete $4;
String target = $5; String target = $6;
free($5); free($6);
if (!ApplyRule::IsValidSourceType(type)) if (!ApplyRule::IsValidSourceType(type))
BOOST_THROW_EXCEPTION(ConfigError("'apply' cannot be used with type '" + type + "'") << errinfo_debuginfo(DebugInfoRange(@2, @3))); BOOST_THROW_EXCEPTION(ConfigError("'apply' cannot be used with type '" + type + "'") << errinfo_debuginfo(DebugInfoRange(@2, @3)));
@ -878,8 +895,8 @@ apply:
BOOST_THROW_EXCEPTION(ConfigError("'apply' target type '" + target + "' is invalid") << errinfo_debuginfo(DebugInfoRange(@2, @5))); BOOST_THROW_EXCEPTION(ConfigError("'apply' target type '" + target + "' is invalid") << errinfo_debuginfo(DebugInfoRange(@2, @5)));
} }
Expression::Ptr exprl = *$6; Expression::Ptr exprl = *$7;
delete $6; delete $7;
exprl->MakeInline(); exprl->MakeInline();
@ -895,11 +912,19 @@ apply:
Expression::Ptr filter = make_shared<Expression>(&Expression::OpLogicalAnd, m_Assign.top(), rex, DebugInfoRange(@2, @5)); Expression::Ptr filter = make_shared<Expression>(&Expression::OpLogicalAnd, m_Assign.top(), rex, DebugInfoRange(@2, @5));
m_Assign.pop(); m_Assign.pop();
String fvar = m_FVar.top();
m_FVar.pop();
Expression::Ptr fterm = m_FTerm.top();
m_FTerm.pop();
Array::Ptr args = make_shared<Array>(); Array::Ptr args = make_shared<Array>();
args->Add(type); args->Add(type);
args->Add(target); args->Add(target);
args->Add(aname); args->Add(aname);
args->Add(filter); args->Add(filter);
args->Add(fvar);
args->Add(fterm);
$$ = new Value(make_shared<Expression>(&Expression::OpApply, args, exprl, DebugInfoRange(@2, @5))); $$ = new Value(make_shared<Expression>(&Expression::OpApply, args, exprl, DebugInfoRange(@2, @5)));
} }

View File

@ -551,10 +551,12 @@ Value Expression::OpApply(const Expression* expr, const Dictionary::Ptr& locals,
String target = left->Get(1); String target = left->Get(1);
Expression::Ptr aname = left->Get(2); Expression::Ptr aname = left->Get(2);
Expression::Ptr filter = left->Get(3); Expression::Ptr filter = left->Get(3);
String fvar = left->Get(4);
Expression::Ptr fterm = left->Get(5);
String name = aname->Evaluate(locals, dhint); String name = aname->Evaluate(locals, dhint);
ApplyRule::AddRule(type, target, name, exprl, filter, expr->m_DebugInfo, locals); ApplyRule::AddRule(type, target, name, exprl, filter, fvar, fterm, expr->m_DebugInfo, locals);
return Empty; return Empty;
} }

View File

@ -167,7 +167,16 @@ void DbObject::SendVarsConfigUpdate(void)
ObjectLock olock (vars); ObjectLock olock (vars);
BOOST_FOREACH(const Dictionary::Pair& kv, vars) { BOOST_FOREACH(const Dictionary::Pair& kv, vars) {
if (!kv.first.IsEmpty()) { if (kv.first.IsEmpty())
continue;
String value;
if (kv.second.IsObjectType<Array>())
value = Utility::Join(kv.second, ';');
else
value = kv.second;
int overridden = custom_var_object->IsVarOverridden(kv.first) ? 1 : 0; int overridden = custom_var_object->IsVarOverridden(kv.first) ? 1 : 0;
Log(LogDebug, "DbObject") Log(LogDebug, "DbObject")
@ -175,8 +184,8 @@ void DbObject::SendVarsConfigUpdate(void)
<< "' overridden: " << overridden; << "' overridden: " << overridden;
Dictionary::Ptr fields = make_shared<Dictionary>(); Dictionary::Ptr fields = make_shared<Dictionary>();
fields->Set("varname", Convert::ToString(kv.first)); fields->Set("varname", kv.first);
fields->Set("varvalue", Convert::ToString(kv.second)); fields->Set("varvalue", value);
fields->Set("config_type", 1); fields->Set("config_type", 1);
fields->Set("has_been_modified", overridden); fields->Set("has_been_modified", overridden);
fields->Set("object_id", obj); fields->Set("object_id", obj);
@ -191,7 +200,6 @@ void DbObject::SendVarsConfigUpdate(void)
} }
} }
} }
}
void DbObject::SendVarsStatusUpdate(void) void DbObject::SendVarsStatusUpdate(void)
{ {
@ -211,7 +219,9 @@ void DbObject::SendVarsStatusUpdate(void)
ObjectLock olock (vars); ObjectLock olock (vars);
BOOST_FOREACH(const Dictionary::Pair& kv, vars) { BOOST_FOREACH(const Dictionary::Pair& kv, vars) {
if (!kv.first.IsEmpty()) { if (kv.first.IsEmpty() || kv.second.IsObject())
continue;
int overridden = custom_var_object->IsVarOverridden(kv.first) ? 1 : 0; int overridden = custom_var_object->IsVarOverridden(kv.first) ? 1 : 0;
Log(LogDebug, "DbObject") Log(LogDebug, "DbObject")
@ -240,8 +250,6 @@ void DbObject::SendVarsStatusUpdate(void)
OnQuery(query); OnQuery(query);
} }
} }
}
} }
double DbObject::GetLastConfigUpdate(void) const double DbObject::GetLastConfigUpdate(void) const

View File

@ -63,12 +63,35 @@ bool Dependency::EvaluateApplyRuleOne(const Checkable::Ptr& checkable, const App
if (!rule.EvaluateFilter(locals)) if (!rule.EvaluateFilter(locals))
return false; return false;
Array::Ptr instances;
if (rule.GetFTerm()) {
Value vinstances = rule.GetFTerm()->Evaluate(locals);
if (!vinstances.IsObjectType<Array>())
BOOST_THROW_EXCEPTION(std::invalid_argument("for expression must be an array"));
instances = vinstances;
} else {
instances = make_shared<Array>();
instances->Add("");
}
ObjectLock olock(instances);
BOOST_FOREACH(const String& instance, instances) {
String objName = rule.GetName();
if (!rule.GetFVar().IsEmpty()) {
locals->Set(rule.GetFVar(), instance);
objName += "-" + instance;
}
Log(LogDebug, "Dependency") Log(LogDebug, "Dependency")
<< "Applying dependency '" << rule.GetName() << "' to object '" << checkable->GetName() << "' for rule " << di; << "Applying dependency '" << rule.GetName() << "' to object '" << checkable->GetName() << "' for rule " << di;
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di); ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
builder->SetType("Dependency"); builder->SetType("Dependency");
builder->SetName(rule.GetName()); builder->SetName(objName);
builder->SetScope(locals); builder->SetScope(locals);
builder->AddExpression(make_shared<Expression>(&Expression::OpSet, builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
@ -103,6 +126,7 @@ bool Dependency::EvaluateApplyRuleOne(const Checkable::Ptr& checkable, const App
dependencyItem->Register(); dependencyItem->Register();
DynamicObject::Ptr dobj = dependencyItem->Commit(); DynamicObject::Ptr dobj = dependencyItem->Commit();
dobj->OnConfigLoaded(); dobj->OnConfigLoaded();
}
return true; return true;
} }

View File

@ -63,12 +63,35 @@ bool Notification::EvaluateApplyRuleOne(const Checkable::Ptr& checkable, const A
if (!rule.EvaluateFilter(locals)) if (!rule.EvaluateFilter(locals))
return false; return false;
Array::Ptr instances;
if (rule.GetFTerm()) {
Value vinstances = rule.GetFTerm()->Evaluate(locals);
if (!vinstances.IsObjectType<Array>())
BOOST_THROW_EXCEPTION(std::invalid_argument("for expression must be an array"));
instances = vinstances;
} else {
instances = make_shared<Array>();
instances->Add("");
}
ObjectLock olock(instances);
BOOST_FOREACH(const String& instance, instances) {
String objName = rule.GetName();
if (!rule.GetFVar().IsEmpty()) {
locals->Set(rule.GetFVar(), instance);
objName += "-" + instance;
}
Log(LogDebug, "Notification") Log(LogDebug, "Notification")
<< "Applying notification '" << rule.GetName() << "' to object '" << checkable->GetName() << "' for rule " << di; << "Applying notification '" << rule.GetName() << "' to object '" << checkable->GetName() << "' for rule " << di;
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di); ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
builder->SetType("Notification"); builder->SetType("Notification");
builder->SetName(rule.GetName()); builder->SetName(objName);
builder->SetScope(locals); builder->SetScope(locals);
builder->AddExpression(make_shared<Expression>(&Expression::OpSet, builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
@ -98,6 +121,7 @@ bool Notification::EvaluateApplyRuleOne(const Checkable::Ptr& checkable, const A
notificationItem->Register(); notificationItem->Register();
DynamicObject::Ptr dobj = notificationItem->Commit(); DynamicObject::Ptr dobj = notificationItem->Commit();
dobj->OnConfigLoaded(); dobj->OnConfigLoaded();
}
return true; return true;
} }

View File

@ -62,12 +62,35 @@ bool ScheduledDowntime::EvaluateApplyRule(const Checkable::Ptr& checkable, const
if (!rule.EvaluateFilter(locals)) if (!rule.EvaluateFilter(locals))
return false; return false;
Array::Ptr instances;
if (rule.GetFTerm()) {
Value vinstances = rule.GetFTerm()->Evaluate(locals);
if (!vinstances.IsObjectType<Array>())
BOOST_THROW_EXCEPTION(std::invalid_argument("for expression must be an array"));
instances = vinstances;
} else {
instances = make_shared<Array>();
instances->Add("");
}
ObjectLock olock(instances);
BOOST_FOREACH(const String& instance, instances) {
String objName = rule.GetName();
if (!rule.GetFVar().IsEmpty()) {
locals->Set(rule.GetFVar(), instance);
objName += "-" + instance;
}
Log(LogDebug, "ScheduledDowntime") Log(LogDebug, "ScheduledDowntime")
<< "Applying scheduled downtime '" << rule.GetName() << "' to object '" << checkable->GetName() << "' for rule " << di; << "Applying scheduled downtime '" << rule.GetName() << "' to object '" << checkable->GetName() << "' for rule " << di;
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di); ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
builder->SetType("ScheduledDowntime"); builder->SetType("ScheduledDowntime");
builder->SetName(rule.GetName()); builder->SetName(objName);
builder->SetScope(locals); builder->SetScope(locals);
builder->AddExpression(make_shared<Expression>(&Expression::OpSet, builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
@ -97,6 +120,7 @@ bool ScheduledDowntime::EvaluateApplyRule(const Checkable::Ptr& checkable, const
downtimeItem->Register(); downtimeItem->Register();
DynamicObject::Ptr dobj = downtimeItem->Commit(); DynamicObject::Ptr dobj = downtimeItem->Commit();
dobj->OnConfigLoaded(); dobj->OnConfigLoaded();
}
return true; return true;
} }

View File

@ -55,12 +55,35 @@ bool Service::EvaluateApplyRuleOne(const Host::Ptr& host, const ApplyRule& rule)
if (!rule.EvaluateFilter(locals)) if (!rule.EvaluateFilter(locals))
return false; return false;
Array::Ptr instances;
if (rule.GetFTerm()) {
Value vinstances = rule.GetFTerm()->Evaluate(locals);
if (!vinstances.IsObjectType<Array>())
BOOST_THROW_EXCEPTION(std::invalid_argument("for expression must be an array"));
instances = vinstances;
} else {
instances = make_shared<Array>();
instances->Add("");
}
ObjectLock olock(instances);
BOOST_FOREACH(const String& instance, instances) {
String objName = rule.GetName();
if (!rule.GetFVar().IsEmpty()) {
locals->Set(rule.GetFVar(), instance);
objName += "-" + instance;
}
Log(LogDebug, "Service") Log(LogDebug, "Service")
<< "Applying service '" << rule.GetName() << "' to host '" << host->GetName() << "' for rule " << di; << "Applying service '" << objName << "' to host '" << host->GetName() << "' for rule " << di;
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di); ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
builder->SetType("Service"); builder->SetType("Service");
builder->SetName(rule.GetName()); builder->SetName(objName);
builder->SetScope(locals); builder->SetScope(locals);
builder->AddExpression(make_shared<Expression>(&Expression::OpSet, builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
@ -70,7 +93,7 @@ bool Service::EvaluateApplyRuleOne(const Host::Ptr& host, const ApplyRule& rule)
builder->AddExpression(make_shared<Expression>(&Expression::OpSet, builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
make_shared<Expression>(&Expression::OpLiteral, "name", di), make_shared<Expression>(&Expression::OpLiteral, "name", di),
make_shared<Expression>(&Expression::OpLiteral, rule.GetName(), di), make_shared<Expression>(&Expression::OpLiteral, objName, di),
di)); di));
String zone = host->GetZone(); String zone = host->GetZone();
@ -88,6 +111,7 @@ bool Service::EvaluateApplyRuleOne(const Host::Ptr& host, const ApplyRule& rule)
serviceItem->Register(); serviceItem->Register();
DynamicObject::Ptr dobj = serviceItem->Commit(); DynamicObject::Ptr dobj = serviceItem->Commit();
dobj->OnConfigLoaded(); dobj->OnConfigLoaded();
}
return true; return true;
} }