AndFilter::AndFilter(void)
{ }
-bool AndFilter::Apply(const Table::Ptr& table, const Object::Ptr& object)
+bool AndFilter::Apply(const Table::Ptr& table, const Value& row)
{
BOOST_FOREACH(const Filter::Ptr& filter, m_Filters) {
- if (!filter->Apply(table, object))
+ if (!filter->Apply(table, row))
return false;
}
AndFilter(void);
- virtual bool Apply(const Table::Ptr& table, const Object::Ptr& object);
+ virtual bool Apply(const Table::Ptr& table, const Value& row);
};
}
: m_Column(column), m_Operator(op), m_Operand(operand)
{ }
-bool AttributeFilter::Apply(const Table::Ptr& table, const Object::Ptr& object)
+bool AttributeFilter::Apply(const Table::Ptr& table, const Value& row)
{
Column column = table->GetColumn(m_Column);
- Value value = column.ExtractValue(object);
+ Value value = column.ExtractValue(row);
if (value.IsObjectType<Array>()) {
if (m_Operator == ">=") {
AttributeFilter(const String& column, const String& op, const String& operand);
- virtual bool Apply(const Table::Ptr& table, const Object::Ptr& object);
+ virtual bool Apply(const Table::Ptr& table, const Value& row);
protected:
String m_Column;
: m_ValueAccessor(valueAccessor), m_ObjectAccessor(objectAccessor)
{ }
-Value Column::ExtractValue(const Object::Ptr& uobject) const
+Value Column::ExtractValue(const Value& urow) const
{
- Object::Ptr object;
+ Value row;
if (!m_ObjectAccessor.empty())
- object = m_ObjectAccessor(uobject);
+ row = m_ObjectAccessor(urow);
else
- object = uobject;
+ row = urow;
- return m_ValueAccessor(object);
+ return m_ValueAccessor(row);
}
class Column
{
public:
- typedef boost::function<Value (const Object::Ptr&)> ValueAccessor;
- typedef boost::function<Object::Ptr (const Object::Ptr&)> ObjectAccessor;
+ typedef boost::function<Value (const Value&)> ValueAccessor;
+ typedef boost::function<Value (const Value&)> ObjectAccessor;
Column(const ValueAccessor& valueAccessor, const ObjectAccessor& objectAccessor);
- Value ExtractValue(const Object::Ptr& uobject) const;
+ Value ExtractValue(const Value& urow) const;
private:
ValueAccessor m_ValueAccessor;
#include "livestatus/commentstable.h"
#include "livestatus/servicestable.h"
-#include "livestatus/hoststable.h"
#include "icinga/service.h"
#include "base/dynamictype.h"
#include "base/objectlock.h"
table->AddColumn(prefix + "expires", Column(&CommentsTable::ExpiresAccessor, objectAccessor));
table->AddColumn(prefix + "expire_time", Column(&CommentsTable::ExpireTimeAccessor, objectAccessor));
- // TODO: Join hosts and services table with prefix
- HostsTable::AddColumns(table, "host_", &CommentsTable::HostAccessor);
ServicesTable::AddColumns(table, "service_", &CommentsTable::ServiceAccessor);
}
ObjectLock olock(comments);
- /*Value comment;
- BOOST_FOREACH(boost::tie(boost::tuples::ignore, comment), comments) {
- addRowFn(comment);
- }*/
String id;
BOOST_FOREACH(boost::tie(id, boost::tuples::ignore), comments) {
addRowFn(id);
}
}
-Object::Ptr CommentsTable::HostAccessor(const Value& row)
-{
- Service::Ptr svc = Service::GetOwnerByCommentID(row);
-
- if (!svc)
- return Value();
-
- return svc->GetHost();
-}
-
Object::Ptr CommentsTable::ServiceAccessor(const Value& row)
{
return Service::GetOwnerByCommentID(row);
{
Dictionary::Ptr comment = Service::GetCommentByID(row);
+ if (!comment)
+ return Value();
+
return comment->Get("author");
}
{
Dictionary::Ptr comment = Service::GetCommentByID(row);
+ if (!comment)
+ return Value();
+
return comment->Get("text");
}
{
Dictionary::Ptr comment = Service::GetCommentByID(row);
+ if (!comment)
+ return Value();
+
return comment->Get("legacy_id");
}
{
Dictionary::Ptr comment = Service::GetCommentByID(row);
+ if (!comment)
+ return Value();
+
return comment->Get("entry_time");
}
{
Service::Ptr svc = Service::GetOwnerByCommentID(row);
+ if (!svc)
+ return Value();
+
return (svc->IsHostCheck() ? 0 : 1);
}
{
Dictionary::Ptr comment = Service::GetCommentByID(row);
+ if (!comment)
+ return Value();
+
return comment->Get("entry_type");
}
{
Dictionary::Ptr comment = Service::GetCommentByID(row);
+ if (!comment)
+ return Value();
+
return comment->Get("expires");
}
{
Dictionary::Ptr comment = Service::GetCommentByID(row);
+ if (!comment)
+ return Value();
+
return comment->Get("expire_time");
}
protected:
virtual void FetchRows(const AddRowFunction& addRowFn);
- static Object::Ptr HostAccessor(const Value& row);
+private:
static Object::Ptr ServiceAccessor(const Value& row);
static Value AuthorAccessor(const Value& row);
******************************************************************************/
#include "livestatus/downtimestable.h"
+#include "livestatus/servicestable.h"
#include "icinga/service.h"
#include "base/dynamictype.h"
#include "base/objectlock.h"
table->AddColumn(prefix + "duration", Column(&DowntimesTable::DurationAccessor, objectAccessor));
table->AddColumn(prefix + "triggered_by", Column(&DowntimesTable::TriggeredByAccessor, objectAccessor));
- // TODO: Join services table.
+ ServicesTable::AddColumns(table, "service_", &DowntimesTable::ServiceAccessor);
}
String DowntimesTable::GetName(void) const
ObjectLock olock(downtimes);
- /*Value downtime;
- BOOST_FOREACH(boost::tie(boost::tuples::ignore, downtime), downtimes) {
- addRowFn(downtime);
- }*/
String id;
BOOST_FOREACH(boost::tie(id, boost::tuples::ignore), downtimes) {
addRowFn(id);
}
}
+Object::Ptr DowntimesTable::ServiceAccessor(const Value& row)
+{
+ return Service::GetOwnerByDowntimeID(row);
+}
+
Value DowntimesTable::AuthorAccessor(const Value& row)
{
Dictionary::Ptr downtime = Service::GetDowntimeByID(row);
Value DowntimesTable::DurationAccessor(const Value& row)
{
- /*
Dictionary::Ptr downtime = Service::GetDowntimeByID(row);
return downtime->Get("duration");
- */
}
Value DowntimesTable::TriggeredByAccessor(const Value& row)
{
- /*
Dictionary::Ptr downtime = Service::GetDowntimeByID(row);
return downtime->Get("triggered_by");
- */
}
protected:
virtual void FetchRows(const AddRowFunction& addRowFn);
+private:
+ static Object::Ptr ServiceAccessor(const Value& row);
+
static Value AuthorAccessor(const Value& row);
static Value CommentAccessor(const Value& row);
static Value IdAccessor(const Value& row);
public:
DECLARE_PTR_TYPEDEFS(Filter);
- virtual bool Apply(const Table::Ptr& table, const Object::Ptr& object) = 0;
+ virtual bool Apply(const Table::Ptr& table, const Value& row) = 0;
protected:
Filter(void);
: m_Inner(inner)
{ }
-bool NegateFilter::Apply(const Table::Ptr& table, const Object::Ptr& object)
+bool NegateFilter::Apply(const Table::Ptr& table, const Value& row)
{
- return !m_Inner->Apply(table, object);
+ return !m_Inner->Apply(table, row);
}
NegateFilter(const Filter::Ptr& inner);
- virtual bool Apply(const Table::Ptr& table, const Object::Ptr& object);
+ virtual bool Apply(const Table::Ptr& table, const Value& row);
private:
Filter::Ptr m_Inner;
OrFilter::OrFilter(void)
{ }
-bool OrFilter::Apply(const Table::Ptr& table, const Object::Ptr& object)
+bool OrFilter::Apply(const Table::Ptr& table, const Value& row)
{
if (m_Filters.empty())
return true;
BOOST_FOREACH(const Filter::Ptr& filter, m_Filters) {
- if (filter->Apply(table, object))
+ if (filter->Apply(table, row))
return true;
}
OrFilter(void);
- virtual bool Apply(const Table::Ptr& table, const Object::Ptr& object);
+ virtual bool Apply(const Table::Ptr& table, const Value& row);
};
}
#include "base/convert.h"
#include "base/objectlock.h"
#include "base/logger_fwd.h"
+#include "base/exception.h"
#include <boost/algorithm/string/classification.hpp>
#include <boost/smart_ptr/make_shared.hpp>
#include <boost/foreach.hpp>
return;
}
- std::vector<Object::Ptr> objects = table->FilterRows(m_Filter);
+ std::vector<Value> objects = table->FilterRows(m_Filter);
std::vector<String> columns;
if (m_Columns.size() > 0)
Array::Ptr rs = boost::make_shared<Array>();
if (m_Stats.empty()) {
- BOOST_FOREACH(const Object::Ptr& object, objects) {
+ BOOST_FOREACH(const Value& object, objects) {
Array::Ptr row = boost::make_shared<Array>();
BOOST_FOREACH(const String& columnName, columns) {
} else {
std::vector<int> stats(m_Stats.size(), 0);
- BOOST_FOREACH(const Object::Ptr& object, objects) {
+ BOOST_FOREACH(const Value& object, objects) {
int index = 0;
BOOST_FOREACH(const Filter::Ptr filter, m_Stats) {
if (filter->Apply(table, object))
bool Query::Execute(const Stream::Ptr& stream)
{
try {
- Log(LogInformation, "livestatus", "Executing livestatus query: " + m_Verb);
-
- if (m_Verb == "GET")
- ExecuteGetHelper(stream);
- else if (m_Verb == "COMMAND")
- ExecuteCommandHelper(stream);
- else if (m_Verb == "ERROR")
- ExecuteErrorHelper(stream);
- else
- BOOST_THROW_EXCEPTION(std::runtime_error("Invalid livestatus query verb."));
+ Log(LogInformation, "livestatus", "Executing livestatus query: " + m_Verb);
+
+ if (m_Verb == "GET")
+ ExecuteGetHelper(stream);
+ else if (m_Verb == "COMMAND")
+ ExecuteCommandHelper(stream);
+ else if (m_Verb == "ERROR")
+ ExecuteErrorHelper(stream);
+ else
+ BOOST_THROW_EXCEPTION(std::runtime_error("Invalid livestatus query verb."));
} catch (const std::exception& ex) {
+ StackTrace *st = Exception::GetLastStackTrace();
+ std::ostringstream info;
+ st->Print(info);
+ Log(LogWarning, "livestatus", info.str());
SendResponse(stream, 452, boost::diagnostic_information(ex));
}
table->AddColumn(prefix + "groups", Column(&ServicesTable::GroupsAccessor, objectAccessor));
table->AddColumn(prefix + "contact_groups", Column(&ServicesTable::ContactGroupsAccessor, objectAccessor));
- HostsTable::AddColumns(table, "host_", &ServicesTable::HostAccessor);
+ HostsTable::AddColumns(table, "host_", boost::bind(&ServicesTable::HostAccessor, _1, objectAccessor));
}
String ServicesTable::GetName(void) const
}
}
-Object::Ptr ServicesTable::HostAccessor(const Value& row)
+Object::Ptr ServicesTable::HostAccessor(const Value& row, const Column::ObjectAccessor& parentObjectAccessor)
{
- return static_cast<Service::Ptr>(row)->GetHost();
+ return static_cast<Service::Ptr>(parentObjectAccessor(row))->GetHost();
}
Value ServicesTable::ShortNameAccessor(const Value& row)
protected:
virtual void FetchRows(const AddRowFunction& addRowFn);
- static Object::Ptr HostAccessor(const Value& row);
+ static Object::Ptr HostAccessor(const Value& row, const Column::ObjectAccessor& parentObjectAccessor);
static Value ShortNameAccessor(const Value& row);
static Value DisplayNameAccessor(const Value& row);
return names;
}
-std::vector<Object::Ptr> Table::FilterRows(const Filter::Ptr& filter)
+std::vector<Value> Table::FilterRows(const Filter::Ptr& filter)
{
- std::vector<Object::Ptr> rs;
+ std::vector<Value> rs;
FetchRows(boost::bind(&Table::FilteredAddRow, this, boost::ref(rs), filter, _1));
return rs;
}
-void Table::FilteredAddRow(std::vector<Object::Ptr>& rs, const Filter::Ptr& filter, const Object::Ptr& object)
+void Table::FilteredAddRow(std::vector<Value>& rs, const Filter::Ptr& filter, const Value& row)
{
- if (!filter || filter->Apply(GetSelf(), object))
- rs.push_back(object);
+ if (!filter || filter->Apply(GetSelf(), row))
+ rs.push_back(row);
}
Value Table::ZeroAccessor(const Object::Ptr&)
virtual String GetName(void) const = 0;
- std::vector<Object::Ptr> FilterRows(const shared_ptr<Filter>& filter);
+ std::vector<Value> FilterRows(const shared_ptr<Filter>& filter);
void AddColumn(const String& name, const Column& column);
Column GetColumn(const String& name) const;
private:
std::map<String, Column> m_Columns;
- void FilteredAddRow(std::vector<Object::Ptr>& rs, const shared_ptr<Filter>& filter, const Object::Ptr& object);
+ void FilteredAddRow(std::vector<Value>& rs, const shared_ptr<Filter>& filter, const Value& row);
};
}