convert.cpp debuginfo.cpp dictionary.cpp dynamicobject.cpp dynamicobject.thpp dynamictype.cpp
exception.cpp fifo.cpp filelogger.cpp filelogger.thpp initialize.cpp json.cpp logger.cpp logger.thpp
netstring.cpp networkstream.cpp object.cpp primitivetype.cpp process.cpp
- ringbuffer.cpp scriptfunction.cpp scriptfunctionwrapper.cpp
+ ringbuffer.cpp scriptfunction.cpp scriptfunctionwrapper.cpp scriptsignal.cpp
scriptutils.cpp scriptvariable.cpp serializer.cpp socket.cpp stacktrace.cpp
statsfunction.cpp stdiostream.cpp stream.cpp streamlogger.cpp streamlogger.thpp string.cpp
sysloglogger.cpp sysloglogger.thpp tcpsocket.cpp thinmutex.cpp threadpool.cpp timer.cpp
--- /dev/null
+/******************************************************************************
+ * Icinga 2 *
+ * Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License *
+ * as published by the Free Software Foundation; either version 2 *
+ * of the License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software Foundation *
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ******************************************************************************/
+
+#include "base/scriptsignal.hpp"
+#include "base/scriptvariable.hpp"
+
+using namespace icinga;
+
+void ScriptSignal::AddSlot(const Callback& slot)
+{
+ m_Slots.push_back(slot);
+}
+
+Value ScriptSignal::Invoke(const std::vector<Value>& arguments)
+{
+ BOOST_FOREACH(const Callback& slot, m_Slots)
+ slot(arguments);
+}
+
+ScriptSignal::Ptr ScriptSignal::GetByName(const String& name)
+{
+ ScriptVariable::Ptr sv = ScriptVariable::GetByName(name);
+
+ if (!sv)
+ return ScriptSignal::Ptr();
+
+ return sv->GetData();
+}
+
+void ScriptSignal::Register(const String& name, const ScriptSignal::Ptr& function)
+{
+ ScriptVariable::Ptr sv = ScriptVariable::Set(name, function);
+ sv->SetConstant(true);
+}
+
+void ScriptSignal::Unregister(const String& name)
+{
+ ScriptVariable::Unregister(name);
+}
+
--- /dev/null
+/******************************************************************************
+ * Icinga 2 *
+ * Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License *
+ * as published by the Free Software Foundation; either version 2 *
+ * of the License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software Foundation *
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ******************************************************************************/
+
+#ifndef SCRIPTSIGNAL_H
+#define SCRIPTSIGNAL_H
+
+#include "base/i2-base.hpp"
+#include "base/value.hpp"
+#include <vector>
+#include <boost/function.hpp>
+
+namespace icinga
+{
+
+/**
+ * A signal that can be subscribed to by scripts.
+ *
+ * @ingroup base
+ */
+class I2_BASE_API ScriptSignal : public Object
+{
+public:
+ DECLARE_PTR_TYPEDEFS(ScriptSignal);
+
+ typedef boost::function<void (const std::vector<Value>& arguments)> Callback;
+
+ void AddSlot(const Callback& slot);
+ Value Invoke(const std::vector<Value>& arguments = std::vector<Value>());
+
+ static ScriptSignal::Ptr GetByName(const String& name);
+ static void Register(const String& name, const ScriptSignal::Ptr& signal);
+ static void Unregister(const String& name);
+
+private:
+ std::vector<Callback> m_Slots;
+};
+
+#define REGISTER_SCRIPTSIGNAL(name) \
+ namespace { namespace UNIQUE_NAME(sig) { namespace sig ## name { \
+ void RegisterSignal(void) { \
+ ScriptSignal::Ptr sig = new icinga::ScriptSignal(); \
+ ScriptSignal::Register(#name, sig); \
+ } \
+ INITIALIZE_ONCE(RegisterSignal); \
+ } } }
+
+}
+
+#endif /* SCRIPTSIGNAL_H */
#include "base/objectlock.hpp"
#include "base/dynamictype.hpp"
#include "base/application.hpp"
+#include "base/configerror.hpp"
#include <boost/foreach.hpp>
#include <boost/regex.hpp>
#include <algorithm>
REGISTER_SCRIPTFUNCTION(keys, &ScriptUtils::Keys);
REGISTER_SCRIPTFUNCTION(random, &Utility::Random);
REGISTER_SCRIPTFUNCTION(__get_object, &ScriptUtils::GetObject);
+REGISTER_SCRIPTFUNCTION(assert, &ScriptUtils::Assert);
bool ScriptUtils::Regex(const String& pattern, const String& text)
{
return dtype->GetObject(name);
}
+void ScriptUtils::Assert(const Value& arg)
+{
+ if (!arg.ToBool())
+ BOOST_THROW_EXCEPTION(ConfigError("Assertion failed"));
+}
+
static Type::Ptr TypeOf(const Value& value);
static Array::Ptr Keys(const Dictionary::Ptr& dict);
static DynamicObject::Ptr GetObject(const String& type, const String& name);
+ static void Assert(const Value& arg);
private:
ScriptUtils(void);
#include "base/convert.hpp"
#include "base/scriptvariable.hpp"
#include "base/context.hpp"
+#include "base/scriptsignal.hpp"
#include "config.h"
#include <boost/program_options.hpp>
#include <boost/tuple/tuple.hpp>
static po::variables_map g_AppParams;
REGISTER_CLICOMMAND("daemon", DaemonCommand);
+REGISTER_SCRIPTSIGNAL(onload);
static String LoadAppType(const String& typeSpec)
{
ScriptVariable::WriteVariablesFile(varsfile);
+ ScriptSignal::Ptr loadSignal = ScriptSignal::GetByName("onload");
+ loadSignal->Invoke();
+
return true;
}
__function return T_FUNCTION;
__return return T_RETURN;
__for return T_FOR;
+__signal return T_SIGNAL;
=\> return T_FOLLOWS;
\<\< return T_SHIFT_LEFT;
\>\> return T_SHIFT_RIGHT;
%token T_FUNCTION "function (T_FUNCTION)"
%token T_RETURN "return (T_RETURN)"
%token T_FOR "for (T_FOR)"
+%token T_SIGNAL "signal (T_SIGNAL)"
%token T_FOLLOWS "=> (T_FOLLOWS)"
%type <text> identifier
$$ = new FunctionExpression("", *$3, aexpr, DebugInfoRange(@1, @5));
delete $3;
}
+ | T_SIGNAL identifier T_SET_ADD rterm
+ {
+ $$ = new SlotExpression($2, $4, DebugInfoRange(@1, @4));
+ free($2);
+ }
| T_FOR '(' identifier T_FOLLOWS identifier T_IN rterm ')' rterm_scope
{
$$ = new ForExpression($3, $5, $7, $9, DebugInfoRange(@1, @9));
#include "base/json.hpp"
#include "base/scriptfunction.hpp"
#include "base/scriptvariable.hpp"
+#include "base/scriptsignal.hpp"
#include "base/utility.hpp"
#include "base/objectlock.hpp"
#include "base/object.hpp"
return func;
}
+static void InvokeSlot(const Value& funcName, const std::vector<Value>& arguments)
+{
+ ScriptFunction::Ptr func;
+
+ if (funcName.IsObjectType<ScriptFunction>())
+ func = funcName;
+ else
+ func = ScriptFunction::GetByName(funcName);
+
+ if (!func)
+ BOOST_THROW_EXCEPTION(ConfigError("Function '" + funcName + "' does not exist."));
+
+ func->Invoke(arguments);
+}
+
+Value SlotExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+{
+ ScriptSignal::Ptr sig = ScriptSignal::GetByName(m_Signal);
+
+ if (!sig)
+ BOOST_THROW_EXCEPTION(ConfigError("Signal '" + m_Signal + "' does not exist."));
+
+ sig->AddSlot(boost::bind(InvokeSlot, m_Slot->Evaluate(context), _1));
+
+ return Empty;
+}
+
Value ApplyExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
{
String name = m_Name->Evaluate(context, dhint);
boost::shared_ptr<Expression> m_Expression;
};
+class I2_CONFIG_API SlotExpression : public DebuggableExpression
+{
+public:
+ SlotExpression(const String& signal, Expression *slot, const DebugInfo& debugInfo = DebugInfo())
+ : DebuggableExpression(debugInfo), m_Signal(signal), m_Slot(slot)
+ { }
+
+protected:
+ virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+
+private:
+ String m_Signal;
+ Expression *m_Slot;
+};
+
class I2_CONFIG_API ApplyExpression : public DebuggableExpression
{
public: