mirror of https://github.com/Icinga/icinga2.git
parent
c3cf7682b9
commit
873e294158
|
@ -205,8 +205,9 @@ int Main(void)
|
|||
String initconfig = Application::GetSysconfDir() + "/icinga2/init.conf";
|
||||
|
||||
if (Utility::PathExists(initconfig)) {
|
||||
ConfigCompilerContext::GetInstance()->Reset();
|
||||
ConfigCompiler::CompileFile(initconfig);
|
||||
ScriptFrame frame;
|
||||
Expression *expression = ConfigCompiler::CompileFile(initconfig);
|
||||
expression->Evaluate(frame);
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
|
|
|
@ -27,7 +27,7 @@ set(base_SOURCES
|
|||
convert.cpp debuginfo.cpp dictionary.cpp dictionary-script.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 number.cpp number-script.cpp object.cpp object-script.cpp primitivetype.cpp process.cpp
|
||||
ringbuffer.cpp scripterror.cpp scriptframe.cpp scriptfunction.cpp scriptfunctionwrapper.cpp scriptglobal.cpp
|
||||
ringbuffer.cpp scriptframe.cpp scriptfunction.cpp scriptfunctionwrapper.cpp scriptglobal.cpp
|
||||
scriptutils.cpp serializer.cpp socket.cpp stacktrace.cpp
|
||||
statsfunction.cpp stdiostream.cpp stream.cpp streamlogger.cpp streamlogger.thpp string.cpp string-script.cpp
|
||||
sysloglogger.cpp sysloglogger.thpp tcpsocket.cpp thinmutex.cpp threadpool.cpp timer.cpp
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "base/initialize.hpp"
|
||||
#include "base/workqueue.hpp"
|
||||
#include "base/context.hpp"
|
||||
#include "base/application.hpp"
|
||||
#include <fstream>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/exception/errinfo_api_function.hpp>
|
||||
|
@ -310,7 +311,7 @@ void DynamicObject::RestoreObjects(const String& filename, int attributeTypes)
|
|||
|
||||
unsigned long restored = 0;
|
||||
|
||||
ParallelWorkQueue upq;
|
||||
WorkQueue upq(25000, Application::GetConcurrency());
|
||||
|
||||
String message;
|
||||
while (NetString::ReadStringFromStream(sfp, &message)) {
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "base/debug.hpp"
|
||||
#include "base/objectlock.hpp"
|
||||
#include "base/convert.hpp"
|
||||
#include "base/scripterror.hpp"
|
||||
#include "base/exception.hpp"
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
|
|
|
@ -153,3 +153,24 @@ String icinga::DiagnosticInformation(boost::exception_ptr eptr)
|
|||
return boost::diagnostic_information(eptr);
|
||||
}
|
||||
|
||||
ScriptError::ScriptError(const String& message)
|
||||
: m_Message(message)
|
||||
{ }
|
||||
|
||||
ScriptError::ScriptError(const String& message, const DebugInfo& di)
|
||||
: m_Message(message), m_DebugInfo(di)
|
||||
{ }
|
||||
|
||||
ScriptError::~ScriptError(void) throw()
|
||||
{ }
|
||||
|
||||
const char *ScriptError::what(void) const throw()
|
||||
{
|
||||
return m_Message.CStr();
|
||||
}
|
||||
|
||||
DebugInfo ScriptError::GetDebugInfo(void) const
|
||||
{
|
||||
return m_DebugInfo;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "base/stacktrace.hpp"
|
||||
#include "base/context.hpp"
|
||||
#include "base/utility.hpp"
|
||||
#include "base/debuginfo.hpp"
|
||||
#include <sstream>
|
||||
#include <boost/exception/errinfo_api_function.hpp>
|
||||
#include <boost/exception/errinfo_errno.hpp>
|
||||
|
@ -42,6 +43,25 @@ namespace icinga
|
|||
class I2_BASE_API user_error : virtual public std::exception, virtual public boost::exception
|
||||
{ };
|
||||
|
||||
/*
|
||||
* @ingroup base
|
||||
*/
|
||||
class I2_BASE_API ScriptError : virtual public user_error
|
||||
{
|
||||
public:
|
||||
ScriptError(const String& message);
|
||||
ScriptError(const String& message, const DebugInfo& di);
|
||||
~ScriptError(void) throw();
|
||||
|
||||
virtual const char *what(void) const throw();
|
||||
|
||||
DebugInfo GetDebugInfo(void) const;
|
||||
|
||||
private:
|
||||
String m_Message;
|
||||
DebugInfo m_DebugInfo;
|
||||
};
|
||||
|
||||
I2_BASE_API StackTrace *GetLastExceptionStack(void);
|
||||
I2_BASE_API void SetLastExceptionStack(const StackTrace& trace);
|
||||
|
||||
|
@ -58,9 +78,23 @@ String DiagnosticInformation(const T& ex, StackTrace *stack = NULL, ContextTrace
|
|||
{
|
||||
std::ostringstream result;
|
||||
|
||||
result << boost::diagnostic_information(ex);
|
||||
const user_error *uex = dynamic_cast<const user_error *>(&ex);
|
||||
|
||||
if (dynamic_cast<const user_error *>(&ex) == NULL) {
|
||||
String message = ex.what();
|
||||
|
||||
if (!uex || message.IsEmpty())
|
||||
result << boost::diagnostic_information(ex);
|
||||
else
|
||||
result << "Error: " << message;
|
||||
|
||||
const ScriptError *dex = dynamic_cast<const ScriptError *>(&ex);
|
||||
|
||||
if (dex && !dex->GetDebugInfo().Path.IsEmpty()) {
|
||||
result << "\nLocation:\n";
|
||||
ShowCodeFragment(result, dex->GetDebugInfo());
|
||||
}
|
||||
|
||||
if (!uex) {
|
||||
if (boost::get_error_info<StackTraceErrorInfo>(ex) == NULL) {
|
||||
result << std::endl;
|
||||
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
/******************************************************************************
|
||||
* 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/scripterror.hpp"
|
||||
#include <sstream>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
ScriptError::ScriptError(const String& message)
|
||||
: m_Message(message)
|
||||
{ }
|
||||
|
||||
ScriptError::ScriptError(const String& message, const DebugInfo& di)
|
||||
: m_Message(message), m_DebugInfo(di)
|
||||
{ }
|
||||
|
||||
ScriptError::~ScriptError(void) throw()
|
||||
{ }
|
||||
|
||||
const char *ScriptError::what(void) const throw()
|
||||
{
|
||||
return m_Message.CStr();
|
||||
}
|
||||
|
||||
DebugInfo ScriptError::GetDebugInfo(void) const
|
||||
{
|
||||
return m_DebugInfo;
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/******************************************************************************
|
||||
* 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 SCRIPTERROR_H
|
||||
#define SCRIPTERROR_H
|
||||
|
||||
#include "base/i2-base.hpp"
|
||||
#include "base/debuginfo.hpp"
|
||||
#include "base/exception.hpp"
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
/*
|
||||
* @ingroup base
|
||||
*/
|
||||
class I2_BASE_API ScriptError : virtual public user_error
|
||||
{
|
||||
public:
|
||||
ScriptError(const String& message);
|
||||
ScriptError(const String& message, const DebugInfo& di);
|
||||
~ScriptError(void) throw();
|
||||
|
||||
virtual const char *what(void) const throw();
|
||||
|
||||
DebugInfo GetDebugInfo(void) const;
|
||||
|
||||
private:
|
||||
String m_Message;
|
||||
DebugInfo m_DebugInfo;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* SCRIPTERROR_H */
|
|
@ -26,7 +26,7 @@
|
|||
#include "base/objectlock.hpp"
|
||||
#include "base/dynamictype.hpp"
|
||||
#include "base/application.hpp"
|
||||
#include "base/scripterror.hpp"
|
||||
#include "base/exception.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
#include <algorithm>
|
||||
|
|
|
@ -22,16 +22,19 @@
|
|||
#include "base/logger.hpp"
|
||||
#include "base/convert.hpp"
|
||||
#include "base/application.hpp"
|
||||
#include "base/exception.hpp"
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/thread/tss.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
int WorkQueue::m_NextID = 1;
|
||||
boost::thread_specific_ptr<WorkQueue *> l_ThreadWorkQueue;
|
||||
|
||||
WorkQueue::WorkQueue(size_t maxItems)
|
||||
: m_ID(m_NextID++), m_MaxItems(maxItems), m_Stopped(false),
|
||||
m_Processing(false), m_ExceptionCallback(WorkQueue::DefaultExceptionCallback)
|
||||
WorkQueue::WorkQueue(size_t maxItems, int threadCount)
|
||||
: m_ID(m_NextID++), m_MaxItems(maxItems), m_ThreadCount(threadCount), m_Spawned(false), m_Stopped(false),
|
||||
m_Processing(0)
|
||||
{
|
||||
m_StatusTimer = new Timer();
|
||||
m_StatusTimer->SetInterval(10);
|
||||
|
@ -45,46 +48,53 @@ WorkQueue::~WorkQueue(void)
|
|||
}
|
||||
|
||||
/**
|
||||
* Enqueues a work item. Work items are guaranteed to be executed in the order
|
||||
* they were enqueued in except when allowInterleaved is true in which case
|
||||
* the new work item might be run immediately if it's being enqueued from
|
||||
* within the WorkQueue thread.
|
||||
* Enqueues a task. Tasks are guaranteed to be executed in the order
|
||||
* they were enqueued in except if there is more than one worker thread or when
|
||||
* allowInterleaved is true in which case the new task might be run
|
||||
* immediately if it's being enqueued from within the WorkQueue thread.
|
||||
*/
|
||||
void WorkQueue::Enqueue(const WorkCallback& callback, bool allowInterleaved)
|
||||
void WorkQueue::Enqueue(const Task& task, bool allowInterleaved)
|
||||
{
|
||||
bool wq_thread = (boost::this_thread::get_id() == GetThreadId());
|
||||
bool wq_thread = IsWorkerThread();
|
||||
|
||||
if (wq_thread && allowInterleaved) {
|
||||
callback();
|
||||
task();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
WorkItem item;
|
||||
item.Callback = callback;
|
||||
item.AllowInterleaved = allowInterleaved;
|
||||
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
|
||||
if (m_Thread.get_id() == boost::thread::id())
|
||||
m_Thread = boost::thread(boost::bind(&WorkQueue::WorkerThreadProc, this));
|
||||
if (!m_Spawned) {
|
||||
for (int i = 0; i < m_ThreadCount; i++) {
|
||||
m_Threads.create_thread(boost::bind(&WorkQueue::WorkerThreadProc, this));
|
||||
}
|
||||
|
||||
m_Spawned = true;
|
||||
}
|
||||
|
||||
if (!wq_thread) {
|
||||
while (m_Items.size() >= m_MaxItems)
|
||||
while (m_Tasks.size() >= m_MaxItems)
|
||||
m_CVFull.wait(lock);
|
||||
}
|
||||
|
||||
m_Items.push_back(item);
|
||||
m_Tasks.push_back(task);
|
||||
|
||||
if (m_Items.size() == 1)
|
||||
if (m_Tasks.size() == 1)
|
||||
m_CVEmpty.notify_all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits until all currently enqueued tasks have completed. This only works reliably
|
||||
* when no other thread is enqueuing new tasks when this method is called.
|
||||
*
|
||||
* @param stop Whether to stop the worker threads
|
||||
*/
|
||||
void WorkQueue::Join(bool stop)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
|
||||
while (m_Processing || !m_Items.empty())
|
||||
while (m_Processing || !m_Tasks.empty())
|
||||
m_CVStarved.wait(lock);
|
||||
|
||||
if (stop) {
|
||||
|
@ -92,33 +102,73 @@ void WorkQueue::Join(bool stop)
|
|||
m_CVEmpty.notify_all();
|
||||
lock.unlock();
|
||||
|
||||
if (m_Thread.joinable())
|
||||
m_Thread.join();
|
||||
m_Threads.join_all();
|
||||
m_Spawned = false;
|
||||
}
|
||||
}
|
||||
|
||||
boost::thread::id WorkQueue::GetThreadId(void) const
|
||||
/**
|
||||
* Checks whether the calling thread is one of the worker threads
|
||||
* for this work queue.
|
||||
*
|
||||
* @returns true if called from one of the worker threads, false otherwise
|
||||
*/
|
||||
bool WorkQueue::IsWorkerThread(void) const
|
||||
{
|
||||
return m_Thread.get_id();
|
||||
WorkQueue **pwq = l_ThreadWorkQueue.get();
|
||||
|
||||
if (!pwq)
|
||||
return false;
|
||||
|
||||
return *pwq == this;
|
||||
}
|
||||
|
||||
void WorkQueue::SetExceptionCallback(const ExceptionCallback& callback)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
|
||||
m_ExceptionCallback = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether any exceptions have occurred while executing tasks for this
|
||||
* work queue. When a custom exception callback is set this method will always
|
||||
* return false.
|
||||
*/
|
||||
bool WorkQueue::HasExceptions(void) const
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
|
||||
return !m_Exceptions.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all exceptions which have occurred for tasks in this work queue. When a
|
||||
* custom exception callback is set this method will always return an empty list.
|
||||
*/
|
||||
std::vector<boost::exception_ptr> WorkQueue::GetExceptions(void) const
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
|
||||
return m_Exceptions;
|
||||
}
|
||||
|
||||
void WorkQueue::ReportExceptions(const String& facility) const
|
||||
{
|
||||
std::vector<boost::exception_ptr> exceptions = GetExceptions();
|
||||
|
||||
BOOST_FOREACH(const boost::exception_ptr& eptr, exceptions) {
|
||||
Log(LogCritical, facility)
|
||||
<< DiagnosticInformation(eptr);
|
||||
}
|
||||
|
||||
Log(LogCritical, facility)
|
||||
<< exceptions.size() << " error" << (exceptions.size() != 1 ? "s" : "");
|
||||
}
|
||||
|
||||
size_t WorkQueue::GetLength(void)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
|
||||
return m_Items.size();
|
||||
}
|
||||
|
||||
void WorkQueue::DefaultExceptionCallback(boost::exception_ptr)
|
||||
{
|
||||
throw;
|
||||
return m_Tasks.size();
|
||||
}
|
||||
|
||||
void WorkQueue::StatusTimerHandler(void)
|
||||
|
@ -126,7 +176,7 @@ void WorkQueue::StatusTimerHandler(void)
|
|||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
|
||||
Log(LogNotice, "WorkQueue")
|
||||
<< "#" << m_ID << " items: " << m_Items.size();
|
||||
<< "#" << m_ID << " tasks: " << m_Tasks.size();
|
||||
}
|
||||
|
||||
void WorkQueue::WorkerThreadProc(void)
|
||||
|
@ -135,67 +185,47 @@ void WorkQueue::WorkerThreadProc(void)
|
|||
idbuf << "WQ #" << m_ID;
|
||||
Utility::SetThreadName(idbuf.str());
|
||||
|
||||
l_ThreadWorkQueue.reset(new WorkQueue *(this));
|
||||
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
|
||||
for (;;) {
|
||||
while (m_Items.empty() && !m_Stopped)
|
||||
while (m_Tasks.empty() && !m_Stopped)
|
||||
m_CVEmpty.wait(lock);
|
||||
|
||||
if (m_Stopped)
|
||||
break;
|
||||
|
||||
std::deque<WorkItem> items;
|
||||
m_Items.swap(items);
|
||||
|
||||
if (items.size() >= m_MaxItems)
|
||||
if (m_Tasks.size() >= m_MaxItems)
|
||||
m_CVFull.notify_all();
|
||||
|
||||
m_Processing = true;
|
||||
Task task = m_Tasks.front();
|
||||
m_Tasks.pop_front();
|
||||
|
||||
m_Processing++;
|
||||
|
||||
lock.unlock();
|
||||
|
||||
BOOST_FOREACH(WorkItem& wi, items) {
|
||||
try {
|
||||
wi.Callback();
|
||||
}
|
||||
catch (const std::exception&) {
|
||||
lock.lock();
|
||||
try {
|
||||
task();
|
||||
} catch (const std::exception&) {
|
||||
lock.lock();
|
||||
|
||||
ExceptionCallback callback = m_ExceptionCallback;
|
||||
if (!m_ExceptionCallback)
|
||||
m_Exceptions.push_back(boost::current_exception());
|
||||
|
||||
lock.unlock();
|
||||
lock.unlock();
|
||||
|
||||
callback(boost::current_exception());
|
||||
}
|
||||
if (m_ExceptionCallback)
|
||||
m_ExceptionCallback(boost::current_exception());
|
||||
}
|
||||
|
||||
lock.lock();
|
||||
|
||||
m_Processing = false;
|
||||
m_Processing--;
|
||||
|
||||
m_CVStarved.notify_all();
|
||||
if (m_Tasks.empty())
|
||||
m_CVStarved.notify_all();
|
||||
}
|
||||
}
|
||||
|
||||
ParallelWorkQueue::ParallelWorkQueue(void)
|
||||
: m_QueueCount(Application::GetConcurrency()),
|
||||
m_Queues(new WorkQueue[m_QueueCount]),
|
||||
m_Index(0)
|
||||
{ }
|
||||
|
||||
ParallelWorkQueue::~ParallelWorkQueue(void)
|
||||
{
|
||||
delete[] m_Queues;
|
||||
}
|
||||
|
||||
void ParallelWorkQueue::Enqueue(const boost::function<void(void)>& callback)
|
||||
{
|
||||
m_Index++;
|
||||
m_Queues[m_Index % m_QueueCount].Enqueue(callback);
|
||||
}
|
||||
|
||||
void ParallelWorkQueue::Join(void)
|
||||
{
|
||||
for (unsigned int i = 0; i < m_QueueCount; i++)
|
||||
m_Queues[i].Join();
|
||||
}
|
||||
|
|
|
@ -32,13 +32,7 @@
|
|||
namespace icinga
|
||||
{
|
||||
|
||||
typedef boost::function<void (void)> WorkCallback;
|
||||
|
||||
struct WorkItem
|
||||
{
|
||||
WorkCallback Callback;
|
||||
bool AllowInterleaved;
|
||||
};
|
||||
typedef boost::function<void (void)> Task;
|
||||
|
||||
/**
|
||||
* A workqueue.
|
||||
|
@ -50,53 +44,43 @@ class I2_BASE_API WorkQueue
|
|||
public:
|
||||
typedef boost::function<void (boost::exception_ptr)> ExceptionCallback;
|
||||
|
||||
WorkQueue(size_t maxItems = 25000);
|
||||
WorkQueue(size_t maxItems = 25000, int threadCount = 1);
|
||||
~WorkQueue(void);
|
||||
|
||||
void Enqueue(const WorkCallback& callback, bool allowInterleaved = false);
|
||||
void Enqueue(const Task& task, bool allowInterleaved = false);
|
||||
void Join(bool stop = false);
|
||||
|
||||
boost::thread::id GetThreadId(void) const;
|
||||
bool IsWorkerThread(void) const;
|
||||
|
||||
size_t GetLength(void);
|
||||
|
||||
void SetExceptionCallback(const ExceptionCallback& callback);
|
||||
|
||||
size_t GetLength(void);
|
||||
bool HasExceptions(void) const;
|
||||
std::vector<boost::exception_ptr> GetExceptions(void) const;
|
||||
void ReportExceptions(const String& facility) const;
|
||||
|
||||
private:
|
||||
int m_ID;
|
||||
static int m_NextID;
|
||||
int m_ThreadCount;
|
||||
bool m_Spawned;
|
||||
|
||||
boost::mutex m_Mutex;
|
||||
mutable boost::mutex m_Mutex;
|
||||
boost::condition_variable m_CVEmpty;
|
||||
boost::condition_variable m_CVFull;
|
||||
boost::condition_variable m_CVStarved;
|
||||
boost::thread m_Thread;
|
||||
boost::thread_group m_Threads;
|
||||
size_t m_MaxItems;
|
||||
bool m_Stopped;
|
||||
bool m_Processing;
|
||||
std::deque<WorkItem> m_Items;
|
||||
int m_Processing;
|
||||
std::deque<Task> m_Tasks;
|
||||
ExceptionCallback m_ExceptionCallback;
|
||||
std::vector<boost::exception_ptr> m_Exceptions;
|
||||
Timer::Ptr m_StatusTimer;
|
||||
|
||||
void WorkerThreadProc(void);
|
||||
void StatusTimerHandler(void);
|
||||
|
||||
static void DefaultExceptionCallback(boost::exception_ptr exp);
|
||||
};
|
||||
|
||||
class I2_BASE_API ParallelWorkQueue
|
||||
{
|
||||
public:
|
||||
ParallelWorkQueue(void);
|
||||
~ParallelWorkQueue(void);
|
||||
|
||||
void Enqueue(const boost::function<void(void)>& callback);
|
||||
void Join(void);
|
||||
|
||||
private:
|
||||
unsigned int m_QueueCount;
|
||||
WorkQueue *m_Queues;
|
||||
unsigned int m_Index;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
******************************************************************************/
|
||||
|
||||
#include "cli/daemoncommand.hpp"
|
||||
#include "config/configcompilercontext.hpp"
|
||||
#include "config/configcompiler.hpp"
|
||||
#include "config/configcompilercontext.hpp"
|
||||
#include "config/configitembuilder.hpp"
|
||||
#include "base/logger.hpp"
|
||||
#include "base/application.hpp"
|
||||
|
@ -60,16 +60,20 @@ static String LoadAppType(const String& typeSpec)
|
|||
return typeSpec.SubStr(index + 1);
|
||||
}
|
||||
|
||||
static void ExecuteExpression(Expression *expression)
|
||||
static bool ExecuteExpression(Expression *expression)
|
||||
{
|
||||
if (!expression)
|
||||
return false;
|
||||
|
||||
try {
|
||||
ScriptFrame frame;
|
||||
expression->Evaluate(frame);
|
||||
} catch (const ScriptError& ex) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
|
||||
} catch (const std::exception& ex) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, DiagnosticInformation(ex));
|
||||
Log(LogCritical, "config", DiagnosticInformation(ex));
|
||||
Application::Exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void IncludeZoneDirRecursive(const String& path)
|
||||
|
@ -95,22 +99,18 @@ static void IncludeNonLocalZone(const String& zonePath)
|
|||
static bool LoadConfigFiles(const boost::program_options::variables_map& vm, const String& appType,
|
||||
const String& objectsFile = String(), const String& varsfile = String())
|
||||
{
|
||||
ConfigCompilerContext::GetInstance()->Reset();
|
||||
|
||||
if (!objectsFile.IsEmpty())
|
||||
ConfigCompilerContext::GetInstance()->OpenObjectsFile(objectsFile);
|
||||
|
||||
if (vm.count("config") > 0) {
|
||||
BOOST_FOREACH(const String& configPath, vm["config"].as<std::vector<std::string> >()) {
|
||||
Expression *expression = ConfigCompiler::CompileFile(configPath);
|
||||
if (expression)
|
||||
ExecuteExpression(expression);
|
||||
ExecuteExpression(expression);
|
||||
delete expression;
|
||||
}
|
||||
} else if (!vm.count("no-config")) {
|
||||
Expression *expression = ConfigCompiler::CompileFile(Application::GetSysconfDir() + "/icinga2/icinga2.conf");
|
||||
if (expression)
|
||||
ExecuteExpression(expression);
|
||||
ExecuteExpression(expression);
|
||||
delete expression;
|
||||
}
|
||||
|
||||
|
@ -127,8 +127,7 @@ static bool LoadConfigFiles(const boost::program_options::variables_map& vm, con
|
|||
String name, fragment;
|
||||
BOOST_FOREACH(boost::tie(name, fragment), ConfigFragmentRegistry::GetInstance()->GetItems()) {
|
||||
Expression *expression = ConfigCompiler::CompileText(name, fragment);
|
||||
if (expression)
|
||||
ExecuteExpression(expression);
|
||||
ExecuteExpression(expression);
|
||||
delete expression;
|
||||
}
|
||||
|
||||
|
@ -138,42 +137,7 @@ static bool LoadConfigFiles(const boost::program_options::variables_map& vm, con
|
|||
ConfigItem::Ptr item = builder->Compile();
|
||||
item->Register();
|
||||
|
||||
bool result = ConfigItem::ValidateItems();
|
||||
|
||||
int warnings = 0, errors = 0;
|
||||
|
||||
BOOST_FOREACH(const ConfigCompilerMessage& message, ConfigCompilerContext::GetInstance()->GetMessages()) {
|
||||
std::ostringstream locbuf;
|
||||
ShowCodeFragment(locbuf, message.Location);
|
||||
String location = locbuf.str();
|
||||
|
||||
String logmsg;
|
||||
|
||||
if (!location.IsEmpty())
|
||||
logmsg = "Location:\n" + location;
|
||||
|
||||
logmsg += String("\nConfig ") + (message.Error ? "error" : "warning") + ": " + message.Text;
|
||||
|
||||
if (message.Error) {
|
||||
Log(LogCritical, "config", logmsg);
|
||||
errors++;
|
||||
} else {
|
||||
Log(LogWarning, "config", logmsg);
|
||||
warnings++;
|
||||
}
|
||||
}
|
||||
|
||||
if (warnings > 0 || errors > 0) {
|
||||
LogSeverity severity;
|
||||
|
||||
if (errors == 0)
|
||||
severity = LogWarning;
|
||||
else
|
||||
severity = LogCritical;
|
||||
|
||||
Log(severity, "config")
|
||||
<< errors << " errors, " << warnings << " warnings.";
|
||||
}
|
||||
bool result = ConfigItem::CommitItems();
|
||||
|
||||
if (!result)
|
||||
return false;
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
#include "cli/replcommand.hpp"
|
||||
#include "config/configcompiler.hpp"
|
||||
#include "config/configcompilercontext.hpp"
|
||||
#include "base/json.hpp"
|
||||
#include "base/console.hpp"
|
||||
#include "base/application.hpp"
|
||||
|
@ -132,22 +131,11 @@ int ReplCommand::Run(const po::variables_map& vm, const std::vector<std::string>
|
|||
Expression *expr;
|
||||
|
||||
try {
|
||||
ConfigCompilerContext::GetInstance()->Reset();
|
||||
|
||||
lines[fileName] = line;
|
||||
|
||||
expr = ConfigCompiler::CompileText(fileName, line);
|
||||
|
||||
bool has_errors = false;
|
||||
|
||||
BOOST_FOREACH(const ConfigCompilerMessage& message, ConfigCompilerContext::GetInstance()->GetMessages()) {
|
||||
if (message.Error)
|
||||
has_errors = true;
|
||||
|
||||
std::cout << (message.Error ? "Error" : "Warning") << ": " << message.Text << "\n";
|
||||
}
|
||||
|
||||
if (expr && !has_errors) {
|
||||
if (expr) {
|
||||
Value result = expr->Evaluate(frame);
|
||||
std::cout << ConsoleColorTag(Console_ForegroundCyan);
|
||||
if (!result.IsObject() || result.IsObjectType<Array>() || result.IsObjectType<Dictionary>())
|
||||
|
|
|
@ -229,8 +229,6 @@ bool RepositoryUtility::AddObject(const String& name, const String& type, const
|
|||
change->Set("command", "add");
|
||||
change->Set("attrs", attrs);
|
||||
|
||||
ConfigCompilerContext::GetInstance()->Reset();
|
||||
|
||||
String fname, fragment;
|
||||
BOOST_FOREACH(boost::tie(fname, fragment), ConfigFragmentRegistry::GetInstance()->GetItems()) {
|
||||
Expression *expression = ConfigCompiler::CompileText(fname, fragment);
|
||||
|
@ -258,25 +256,13 @@ bool RepositoryUtility::AddObject(const String& name, const String& type, const
|
|||
Object::Ptr object = dtype->Instantiate();
|
||||
Deserialize(object, vattrs, false, FAConfig);
|
||||
|
||||
RepositoryTypeRuleUtilities utils;
|
||||
ctype->ValidateItem(name, object, DebugInfo(), &utils);
|
||||
|
||||
int warnings = 0, errors = 0;
|
||||
|
||||
BOOST_FOREACH(const ConfigCompilerMessage& message, ConfigCompilerContext::GetInstance()->GetMessages()) {
|
||||
String logmsg = String("Config ") + (message.Error ? "error" : "warning") + ": " + message.Text;
|
||||
|
||||
if (message.Error) {
|
||||
Log(LogCritical, "config", logmsg);
|
||||
errors++;
|
||||
} else {
|
||||
Log(LogWarning, "config", logmsg);
|
||||
warnings++;
|
||||
}
|
||||
}
|
||||
|
||||
if (errors > 0)
|
||||
try {
|
||||
RepositoryTypeRuleUtilities utils;
|
||||
ctype->ValidateItem(name, object, DebugInfo(), &utils);
|
||||
} catch (const ScriptError& ex) {
|
||||
Log(LogCritical, "config", DiagnosticInformation(ex));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (CheckChangeExists(change)) {
|
||||
|
|
|
@ -570,8 +570,8 @@ void CompatLogger::ValidateRotationMethod(const String& location, const CompatLo
|
|||
|
||||
if (rotation_method != "HOURLY" && rotation_method != "DAILY" &&
|
||||
rotation_method != "WEEKLY" && rotation_method != "MONTHLY" && rotation_method != "NONE") {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
||||
location + ": Rotation method '" + rotation_method + "' is invalid.");
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": Rotation method '" + rotation_method + "' is invalid.", GetDebugInfo()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include "base/utility.hpp"
|
||||
#include "base/exception.hpp"
|
||||
#include "base/dynamictype.hpp"
|
||||
#include "base/scripterror.hpp"
|
||||
#include "base/exception.hpp"
|
||||
#include <sstream>
|
||||
#include <stack>
|
||||
#include <boost/foreach.hpp>
|
||||
|
|
|
@ -27,39 +27,6 @@
|
|||
|
||||
using namespace icinga;
|
||||
|
||||
void ConfigCompilerContext::AddMessage(bool error, const String& message, const DebugInfo& di)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
|
||||
m_Messages.push_back(ConfigCompilerMessage(error, message, di));
|
||||
}
|
||||
|
||||
std::vector<ConfigCompilerMessage> ConfigCompilerContext::GetMessages(void) const
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
|
||||
return m_Messages;
|
||||
}
|
||||
|
||||
bool ConfigCompilerContext::HasErrors(void) const
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
|
||||
BOOST_FOREACH(const ConfigCompilerMessage& message, m_Messages) {
|
||||
if (message.Error)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ConfigCompilerContext::Reset(void)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
|
||||
m_Messages.clear();
|
||||
}
|
||||
|
||||
ConfigCompilerContext *ConfigCompilerContext::GetInstance(void)
|
||||
{
|
||||
return Singleton<ConfigCompilerContext>::GetInstance();
|
||||
|
|
|
@ -47,12 +47,6 @@ struct I2_CONFIG_API ConfigCompilerMessage
|
|||
class I2_CONFIG_API ConfigCompilerContext
|
||||
{
|
||||
public:
|
||||
void AddMessage(bool error, const String& message, const DebugInfo& di = DebugInfo());
|
||||
std::vector<ConfigCompilerMessage> GetMessages(void) const;
|
||||
bool HasErrors(void) const;
|
||||
|
||||
void Reset(void);
|
||||
|
||||
void OpenObjectsFile(const String& filename);
|
||||
void WriteObject(const Dictionary::Ptr& object);
|
||||
void FinishObjectsFile(void);
|
||||
|
@ -60,7 +54,6 @@ public:
|
|||
static ConfigCompilerContext *GetInstance(void);
|
||||
|
||||
private:
|
||||
std::vector<ConfigCompilerMessage> m_Messages;
|
||||
String m_ObjectsPath;
|
||||
StdioStream::Ptr m_ObjectsFP;
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include "base/netstring.hpp"
|
||||
#include "base/serializer.hpp"
|
||||
#include "base/json.hpp"
|
||||
#include "base/scripterror.hpp"
|
||||
#include "base/exception.hpp"
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <boost/foreach.hpp>
|
||||
|
@ -163,16 +163,10 @@ DynamicObject::Ptr ConfigItem::Commit(bool discard)
|
|||
|
||||
DebugHint debugHints;
|
||||
|
||||
try {
|
||||
ScriptFrame frame(dobj);
|
||||
if (m_Scope)
|
||||
m_Scope->CopyTo(frame.Locals);
|
||||
m_Expression->Evaluate(frame, &debugHints);
|
||||
} catch (const ScriptError& ex) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
|
||||
} catch (const std::exception& ex) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, DiagnosticInformation(ex));
|
||||
}
|
||||
ScriptFrame frame(dobj);
|
||||
if (m_Scope)
|
||||
m_Scope->CopyTo(frame.Locals);
|
||||
m_Expression->Evaluate(frame, &debugHints);
|
||||
|
||||
if (discard)
|
||||
m_Expression.reset();
|
||||
|
@ -222,18 +216,9 @@ DynamicObject::Ptr ConfigItem::Commit(bool discard)
|
|||
|
||||
ConfigType::Ptr ctype = ConfigType::GetByName(GetType());
|
||||
|
||||
if (!ctype)
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(false, "No validation type found for object '" + GetName() + "' of type '" + GetType() + "'");
|
||||
else {
|
||||
if (ctype)
|
||||
TypeRuleUtilities utils;
|
||||
|
||||
try {
|
||||
ctype->ValidateItem(GetName(), dobj, GetDebugInfo(), &utils);
|
||||
} catch (const ScriptError& ex) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
|
||||
} catch (const std::exception& ex) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, DiagnosticInformation(ex));
|
||||
}
|
||||
ctype->ValidateItem(GetName(), dobj, GetDebugInfo(), &utils);
|
||||
}
|
||||
|
||||
dobj->Register();
|
||||
|
@ -287,7 +272,7 @@ ConfigItem::Ptr ConfigItem::GetObject(const String& type, const String& name)
|
|||
}
|
||||
}
|
||||
|
||||
bool ConfigItem::CommitNewItems(ParallelWorkQueue& upq)
|
||||
bool ConfigItem::CommitNewItems(WorkQueue& upq)
|
||||
{
|
||||
typedef std::pair<ConfigItem::Ptr, bool> ItemPair;
|
||||
std::vector<ItemPair> items;
|
||||
|
@ -320,7 +305,7 @@ bool ConfigItem::CommitNewItems(ParallelWorkQueue& upq)
|
|||
|
||||
upq.Join();
|
||||
|
||||
if (ConfigCompilerContext::GetInstance()->HasErrors())
|
||||
if (upq.HasExceptions())
|
||||
return false;
|
||||
|
||||
std::vector<ConfigItem::Ptr> new_items;
|
||||
|
@ -340,22 +325,18 @@ bool ConfigItem::CommitNewItems(ParallelWorkQueue& upq)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ConfigItem::ValidateItems(void)
|
||||
bool ConfigItem::CommitItems(void)
|
||||
{
|
||||
ParallelWorkQueue upq;
|
||||
|
||||
if (ConfigCompilerContext::GetInstance()->HasErrors())
|
||||
return false;
|
||||
WorkQueue upq(25000, Application::GetConcurrency());
|
||||
|
||||
Log(LogInformation, "ConfigItem", "Committing config items");
|
||||
|
||||
if (!CommitNewItems(upq))
|
||||
if (!CommitNewItems(upq)) {
|
||||
upq.ReportExceptions("config");
|
||||
return false;
|
||||
}
|
||||
|
||||
ApplyRule::CheckMatches();
|
||||
ApplyRule::DiscardRules();
|
||||
|
||||
ConfigItem::DiscardItems();
|
||||
ConfigType::DiscardTypes();
|
||||
|
||||
/* log stats for external parsers */
|
||||
|
@ -366,14 +347,11 @@ bool ConfigItem::ValidateItems(void)
|
|||
<< "Checked " << count << " " << type->GetName() << "(s).";
|
||||
}
|
||||
|
||||
return !ConfigCompilerContext::GetInstance()->HasErrors();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConfigItem::ActivateItems(void)
|
||||
{
|
||||
if (ConfigCompilerContext::GetInstance()->HasErrors())
|
||||
return false;
|
||||
|
||||
/* restore the previous program state */
|
||||
try {
|
||||
DynamicObject::RestoreObjects(Application::GetStatePath());
|
||||
|
@ -384,7 +362,7 @@ bool ConfigItem::ActivateItems(void)
|
|||
|
||||
Log(LogInformation, "ConfigItem", "Triggering Start signal for config items");
|
||||
|
||||
ParallelWorkQueue upq;
|
||||
WorkQueue upq(25000, Application::GetConcurrency());
|
||||
|
||||
BOOST_FOREACH(const DynamicType::Ptr& type, DynamicType::GetTypes()) {
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, type->GetObjects()) {
|
||||
|
@ -414,13 +392,6 @@ bool ConfigItem::ActivateItems(void)
|
|||
return true;
|
||||
}
|
||||
|
||||
void ConfigItem::DiscardItems(void)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
|
||||
m_Items.clear();
|
||||
}
|
||||
|
||||
std::vector<ConfigItem::Ptr> ConfigItem::GetItems(const String& type)
|
||||
{
|
||||
std::vector<ConfigItem::Ptr> items;
|
||||
|
|
|
@ -64,9 +64,8 @@ public:
|
|||
static ConfigItem::Ptr GetObject(const String& type,
|
||||
const String& name);
|
||||
|
||||
static bool ValidateItems(void);
|
||||
static bool CommitItems(void);
|
||||
static bool ActivateItems(void);
|
||||
static void DiscardItems(void);
|
||||
|
||||
static std::vector<ConfigItem::Ptr> GetItems(const String& type);
|
||||
|
||||
|
@ -96,7 +95,7 @@ private:
|
|||
static ConfigItem::Ptr GetObjectUnlocked(const String& type,
|
||||
const String& name);
|
||||
|
||||
static bool CommitNewItems(ParallelWorkQueue& upq);
|
||||
static bool CommitNewItems(WorkQueue& upq);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -136,14 +136,14 @@ void ConfigType::ValidateAttribute(const String& key, const Value& value,
|
|||
}
|
||||
|
||||
if (overallResult == ValidationUnknownField)
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Unknown attribute: " + LocationToString(locations));
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Unknown attribute: " + LocationToString(locations)));
|
||||
else if (overallResult == ValidationInvalidType) {
|
||||
String message = "Invalid value: " + LocationToString(locations);
|
||||
|
||||
if (!hint.IsEmpty())
|
||||
message += ": " + hint;
|
||||
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, message);
|
||||
BOOST_THROW_EXCEPTION(ScriptError(message));
|
||||
}
|
||||
|
||||
if (!subRuleLists.empty() && value.IsObject() && !value.IsObjectType<Array>())
|
||||
|
@ -164,10 +164,8 @@ void ConfigType::ValidateObject(const Object::Ptr& object,
|
|||
|
||||
Value value = VMOps::GetField(object, require);
|
||||
|
||||
if (value.IsEmpty() || (value.IsString() && static_cast<String>(value).IsEmpty())) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true,
|
||||
"Required attribute is missing: " + LocationToString(locations));
|
||||
}
|
||||
if (value.IsEmpty() || (value.IsString() && static_cast<String>(value).IsEmpty()))
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Required attribute is missing: " + LocationToString(locations)));
|
||||
|
||||
locations.pop_back();
|
||||
}
|
||||
|
@ -223,10 +221,8 @@ void ConfigType::ValidateArray(const Array::Ptr& array,
|
|||
|
||||
locations.push_back("Attribute '" + require + "'");
|
||||
|
||||
if (array->GetLength() < index) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true,
|
||||
"Required array index is missing: " + LocationToString(locations));
|
||||
}
|
||||
if (array->GetLength() < index)
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Required array index is missing: " + LocationToString(locations)));
|
||||
|
||||
locations.pop_back();
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "base/json.hpp"
|
||||
#include "base/object.hpp"
|
||||
#include "base/logger.hpp"
|
||||
#include "base/scripterror.hpp"
|
||||
#include "base/exception.hpp"
|
||||
#include "base/scriptglobal.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/exception_ptr.hpp>
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include "base/array.hpp"
|
||||
#include "base/dictionary.hpp"
|
||||
#include "base/scriptfunction.hpp"
|
||||
#include "base/scripterror.hpp"
|
||||
#include "base/exception.hpp"
|
||||
#include "base/scriptframe.hpp"
|
||||
#include "base/convert.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include "base/dictionary.hpp"
|
||||
#include "base/scriptfunction.hpp"
|
||||
#include "base/scriptglobal.hpp"
|
||||
#include "base/scripterror.hpp"
|
||||
#include "base/exception.hpp"
|
||||
#include "base/convert.hpp"
|
||||
#include "base/objectlock.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
|
|
|
@ -424,7 +424,7 @@ void DbConnection::PrepareDatabase(void)
|
|||
void DbConnection::ValidateFailoverTimeout(const String& location, const DbConnection::Ptr& object)
|
||||
{
|
||||
if (object->GetFailoverTimeout() < 60) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
||||
location + ": Failover timeout minimum is 60s.");
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": Failover timeout minimum is 60s.", GetDebugInfo()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,7 +115,7 @@ void IdoMysqlConnection::ExceptionHandler(boost::exception_ptr exp)
|
|||
|
||||
void IdoMysqlConnection::AssertOnWorkQueue(void)
|
||||
{
|
||||
ASSERT(boost::this_thread::get_id() == m_QueryQueue.GetThreadId());
|
||||
ASSERT(m_QueryQueue.IsWorkerThread());
|
||||
}
|
||||
|
||||
void IdoMysqlConnection::Disconnect(void)
|
||||
|
|
|
@ -116,7 +116,7 @@ void IdoPgsqlConnection::ExceptionHandler(boost::exception_ptr exp)
|
|||
|
||||
void IdoPgsqlConnection::AssertOnWorkQueue(void)
|
||||
{
|
||||
ASSERT(boost::this_thread::get_id() == m_QueryQueue.GetThreadId());
|
||||
ASSERT(m_QueryQueue.IsWorkerThread());
|
||||
}
|
||||
|
||||
void IdoPgsqlConnection::Disconnect(void)
|
||||
|
|
|
@ -270,7 +270,7 @@ Endpoint::Ptr Checkable::GetCommandEndpoint(void) const
|
|||
void Checkable::ValidateCheckInterval(const String& location, const Checkable::Ptr& object)
|
||||
{
|
||||
if (object->GetCheckInterval() <= 0) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
||||
location + ": check_interval must be greater than 0.");
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": check_interval must be greater than 0.", GetDebugInfo()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,8 +47,8 @@ void Command::SetModifiedAttributes(int flags, const MessageOrigin& origin)
|
|||
void Command::ValidateAttributes(const String& location, const Command::Ptr& object)
|
||||
{
|
||||
if (object->GetArguments() != Empty && !object->GetCommandLine().IsObjectType<Array>()) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
||||
location + ": Attribute 'command' must be an array if the 'arguments' attribute is set.");
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": Attribute 'command' must be an array if the 'arguments' attribute is set.", GetDebugInfo()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "base/logger.hpp"
|
||||
#include "base/context.hpp"
|
||||
#include "base/workqueue.hpp"
|
||||
#include "base/scripterror.hpp"
|
||||
#include "base/exception.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
@ -150,12 +150,8 @@ void Dependency::EvaluateApplyRules(const Host::Ptr& host)
|
|||
if (rule.GetTargetType() != "Host")
|
||||
continue;
|
||||
|
||||
try {
|
||||
if (EvaluateApplyRule(host, rule))
|
||||
rule.AddMatch();
|
||||
} catch (const ScriptError& ex) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
|
||||
}
|
||||
if (EvaluateApplyRule(host, rule))
|
||||
rule.AddMatch();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,11 +163,7 @@ void Dependency::EvaluateApplyRules(const Service::Ptr& service)
|
|||
if (rule.GetTargetType() != "Service")
|
||||
continue;
|
||||
|
||||
try {
|
||||
if (EvaluateApplyRule(service, rule))
|
||||
rule.AddMatch();
|
||||
} catch (const ScriptError& ex) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
|
||||
}
|
||||
if (EvaluateApplyRule(service, rule))
|
||||
rule.AddMatch();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -208,12 +208,12 @@ void Dependency::ValidateFilters(const String& location, const Dependency::Ptr&
|
|||
int sfilter = FilterArrayToInt(object->GetStates(), 0);
|
||||
|
||||
if (object->GetParentServiceName().IsEmpty() && (sfilter & ~(StateFilterUp | StateFilterDown)) != 0) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
||||
location + ": State filter is invalid for host dependency.");
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": State filter is invalid for host dependency.", GetDebugInfo()));
|
||||
}
|
||||
|
||||
if (!object->GetParentServiceName().IsEmpty() && (sfilter & ~(StateFilterOK | StateFilterWarning | StateFilterCritical | StateFilterUnknown)) != 0) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
||||
location + ": State filter is invalid for service dependency.");
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": State filter is invalid for service dependency.", GetDebugInfo()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include "icinga/pluginutility.hpp"
|
||||
#include "icinga/scheduleddowntime.hpp"
|
||||
#include "config/configcompilercontext.hpp"
|
||||
#include "base/scripterror.hpp"
|
||||
#include "base/exception.hpp"
|
||||
#include "base/objectlock.hpp"
|
||||
#include "base/convert.hpp"
|
||||
#include "base/utility.hpp"
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "base/logger.hpp"
|
||||
#include "base/context.hpp"
|
||||
#include "base/workqueue.hpp"
|
||||
#include "base/scripterror.hpp"
|
||||
#include "base/exception.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
@ -150,12 +150,8 @@ void Notification::EvaluateApplyRules(const Host::Ptr& host)
|
|||
if (rule.GetTargetType() != "Host")
|
||||
continue;
|
||||
|
||||
try {
|
||||
if (EvaluateApplyRule(host, rule))
|
||||
rule.AddMatch();
|
||||
} catch (const ScriptError& ex) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
|
||||
}
|
||||
if (EvaluateApplyRule(host, rule))
|
||||
rule.AddMatch();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,11 +163,7 @@ void Notification::EvaluateApplyRules(const Service::Ptr& service)
|
|||
if (rule.GetTargetType() != "Service")
|
||||
continue;
|
||||
|
||||
try {
|
||||
if (EvaluateApplyRule(service, rule))
|
||||
rule.AddMatch();
|
||||
} catch (const ScriptError& ex) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
|
||||
}
|
||||
if (EvaluateApplyRule(service, rule))
|
||||
rule.AddMatch();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -501,13 +501,13 @@ void Notification::ValidateFilters(const String& location, const Notification::P
|
|||
int sfilter = FilterArrayToInt(object->GetStates(), 0);
|
||||
|
||||
if (object->GetServiceName().IsEmpty() && (sfilter & ~(StateFilterUp | StateFilterDown)) != 0) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
||||
location + ": State filter is invalid.");
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": State filter is invalid.", GetDebugInfo()));
|
||||
}
|
||||
|
||||
if (!object->GetServiceName().IsEmpty() && (sfilter & ~(StateFilterOK | StateFilterWarning | StateFilterCritical | StateFilterUnknown)) != 0) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
||||
location + ": State filter is invalid.");
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": State filter is invalid.", GetDebugInfo()));
|
||||
}
|
||||
|
||||
int tfilter = FilterArrayToInt(object->GetTypes(), 0);
|
||||
|
@ -515,8 +515,8 @@ void Notification::ValidateFilters(const String& location, const Notification::P
|
|||
if ((tfilter & ~(1 << NotificationDowntimeStart | 1 << NotificationDowntimeEnd | 1 << NotificationDowntimeRemoved |
|
||||
1 << NotificationCustom | 1 << NotificationAcknowledgement | 1 << NotificationProblem | 1 << NotificationRecovery |
|
||||
1 << NotificationFlappingStart | 1 << NotificationFlappingEnd)) != 0) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
||||
location + ": Type filter is invalid.");
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": Type filter is invalid.", GetDebugInfo()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "base/dynamictype.hpp"
|
||||
#include "base/logger.hpp"
|
||||
#include "base/context.hpp"
|
||||
#include "base/scripterror.hpp"
|
||||
#include "base/exception.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
@ -148,12 +148,8 @@ void ScheduledDowntime::EvaluateApplyRules(const Host::Ptr& host)
|
|||
if (rule.GetTargetType() != "Host")
|
||||
continue;
|
||||
|
||||
try {
|
||||
if (EvaluateApplyRule(host, rule))
|
||||
rule.AddMatch();
|
||||
} catch (const ScriptError& ex) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
|
||||
}
|
||||
if (EvaluateApplyRule(host, rule))
|
||||
rule.AddMatch();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,11 +161,7 @@ void ScheduledDowntime::EvaluateApplyRules(const Service::Ptr& service)
|
|||
if (rule.GetTargetType() != "Service")
|
||||
continue;
|
||||
|
||||
try {
|
||||
if (EvaluateApplyRule(service, rule))
|
||||
rule.AddMatch();
|
||||
} catch (const ScriptError& ex) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
|
||||
}
|
||||
if (EvaluateApplyRule(service, rule))
|
||||
rule.AddMatch();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "base/logger.hpp"
|
||||
#include "base/context.hpp"
|
||||
#include "base/workqueue.hpp"
|
||||
#include "base/scripterror.hpp"
|
||||
#include "base/exception.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
@ -133,11 +133,7 @@ void Service::EvaluateApplyRules(const Host::Ptr& host)
|
|||
BOOST_FOREACH(ApplyRule& rule, ApplyRule::GetRules("Service")) {
|
||||
CONTEXT("Evaluating 'apply' rules for host '" + host->GetName() + "'");
|
||||
|
||||
try {
|
||||
if (EvaluateApplyRule(host, rule))
|
||||
rule.AddMatch();
|
||||
} catch (const ScriptError& ex) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
|
||||
}
|
||||
if (EvaluateApplyRule(host, rule))
|
||||
rule.AddMatch();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,8 +106,8 @@ void User::ValidateFilters(const String& location, const Dictionary::Ptr& attrs)
|
|||
int sfilter = FilterArrayToInt(attrs->Get("states"), 0);
|
||||
|
||||
if ((sfilter & ~(StateFilterUp | StateFilterDown | StateFilterOK | StateFilterWarning | StateFilterCritical | StateFilterUnknown)) != 0) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
||||
location + ": State filter is invalid.");
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": State filter is invalid.", GetDebugInfo()));
|
||||
}
|
||||
|
||||
int tfilter = FilterArrayToInt(attrs->Get("types"), 0);
|
||||
|
@ -115,8 +115,8 @@ void User::ValidateFilters(const String& location, const Dictionary::Ptr& attrs)
|
|||
if ((tfilter & ~(1 << NotificationDowntimeStart | 1 << NotificationDowntimeEnd | 1 << NotificationDowntimeRemoved |
|
||||
1 << NotificationCustom | 1 << NotificationAcknowledgement | 1 << NotificationProblem | 1 << NotificationRecovery |
|
||||
1 << NotificationFlappingStart | 1 << NotificationFlappingEnd)) != 0) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
||||
location + ": Type filter is invalid.");
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": Type filter is invalid.", GetDebugInfo()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -188,7 +188,7 @@ void LivestatusListener::ValidateSocketType(const String& location, const Livest
|
|||
String socket_type = object->GetSocketType();
|
||||
|
||||
if (socket_type != "unix" && socket_type != "tcp") {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
||||
location + ": Socket type '" + socket_type + "' is invalid.");
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": Socket type '" + socket_type + "' is invalid.", GetDebugInfo()));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue