diff --git a/lib/base/dynamicobject.cpp b/lib/base/dynamicobject.cpp index 229e4e5b3..91175af36 100644 --- a/lib/base/dynamicobject.cpp +++ b/lib/base/dynamicobject.cpp @@ -177,6 +177,14 @@ void DynamicObject::Register(void) dtype->RegisterObject(this); } +void DynamicObject::Unregister(void) +{ + ASSERT(!OwnsLock()); + + DynamicType::Ptr dtype = GetType(); + dtype->UnregisterObject(this); +} + void DynamicObject::Start(void) { ASSERT(!OwnsLock()); diff --git a/lib/base/dynamicobject.hpp b/lib/base/dynamicobject.hpp index 1a60e0f3d..8bca65ef2 100644 --- a/lib/base/dynamicobject.hpp +++ b/lib/base/dynamicobject.hpp @@ -58,6 +58,7 @@ public: bool IsAttributeModified(const String& attr) const; void Register(void); + void Unregister(void); void Activate(void); void Deactivate(void); diff --git a/lib/base/dynamicobject.ti b/lib/base/dynamicobject.ti index 8724ac19e..c45dfc50f 100644 --- a/lib/base/dynamicobject.ti +++ b/lib/base/dynamicobject.ti @@ -34,6 +34,7 @@ enum HAMode class NameComposer { public: virtual String MakeName(const String& shortName, const Object::Ptr& context) const = 0; + virtual Dictionary::Ptr ParseName(const String& name) const = 0; }; }}} diff --git a/lib/base/dynamictype.cpp b/lib/base/dynamictype.cpp index 27b84eb31..e6386dcd8 100644 --- a/lib/base/dynamictype.cpp +++ b/lib/base/dynamictype.cpp @@ -113,6 +113,18 @@ void DynamicType::RegisterObject(const DynamicObject::Ptr& object) } } +void DynamicType::UnregisterObject(const DynamicObject::Ptr& object) +{ + String name = object->GetName(); + + { + ObjectLock olock(this); + + m_ObjectMap.erase(name); + m_ObjectVector.erase(std::remove(m_ObjectVector.begin(), m_ObjectVector.end(), object), m_ObjectVector.end()); + } +} + DynamicObject::Ptr DynamicType::GetObject(const String& name) const { ObjectLock olock(this); diff --git a/lib/base/dynamictype.hpp b/lib/base/dynamictype.hpp index 3c0abb788..9670857e2 100644 --- a/lib/base/dynamictype.hpp +++ b/lib/base/dynamictype.hpp @@ -46,6 +46,7 @@ public: DynamicObject::Ptr GetObject(const String& name) const; void RegisterObject(const DynamicObject::Ptr& object); + void UnregisterObject(const DynamicObject::Ptr& object); static std::vector GetTypes(void); std::pair, DynamicTypeIterator > GetObjects(void); diff --git a/lib/base/type.cpp b/lib/base/type.cpp index 01a209ced..b8058bb45 100644 --- a/lib/base/type.cpp +++ b/lib/base/type.cpp @@ -56,6 +56,16 @@ Type::Ptr Type::GetByName(const String& name) return ptype; } +String Type::GetPluralName(void) const +{ + String name = GetName(); + + if (name[name.GetLength() - 1] == 'y') + return name.SubStr(0, name.GetLength() - 1) + "ies"; + else + return name + "s"; +} + Object::Ptr Type::Instantiate(void) const { ObjectFactory factory = GetFactory(); diff --git a/lib/base/type.hpp b/lib/base/type.hpp index 42189a3c9..c373be00a 100644 --- a/lib/base/type.hpp +++ b/lib/base/type.hpp @@ -80,6 +80,8 @@ public: virtual Field GetFieldInfo(int id) const = 0; virtual int GetFieldCount(void) const = 0; + String GetPluralName(void) const; + Object::Ptr Instantiate(void) const; bool IsAssignableFrom(const Type::Ptr& other) const; diff --git a/lib/cli/daemoncommand.cpp b/lib/cli/daemoncommand.cpp index 39fedd495..7c9b6a625 100644 --- a/lib/cli/daemoncommand.cpp +++ b/lib/cli/daemoncommand.cpp @@ -258,10 +258,14 @@ int DaemonCommand::Run(const po::variables_map& vm, const std::vector& configs, if (!DaemonUtility::ValidateConfigFiles(configs, objectsFile)) return false; - bool result = ConfigItem::CommitItems(); + WorkQueue upq(25000, Application::GetConcurrency()); + bool result = ConfigItem::CommitItems(upq); if (!result) return false; diff --git a/lib/config/configitem.cpp b/lib/config/configitem.cpp index d0e02e9c2..82930ff5e 100644 --- a/lib/config/configitem.cpp +++ b/lib/config/configitem.cpp @@ -268,6 +268,19 @@ void ConfigItem::Register(void) } } +/** + * Unregisters the configuration item. + */ +void ConfigItem::Unregister(void) +{ + if (m_Object) + m_Object->Unregister(); + + boost::mutex::scoped_lock lock(m_Mutex); + m_UnnamedItems.erase(std::remove(m_UnnamedItems.begin(), m_UnnamedItems.end(), this), m_UnnamedItems.end()); + m_Items[m_Type].erase(m_Name); +} + /** * Retrieves a configuration item by type and name. * @@ -292,7 +305,7 @@ ConfigItem::Ptr ConfigItem::GetObject(const String& type, const String& name) return it2->second; } -bool ConfigItem::CommitNewItems(WorkQueue& upq) +bool ConfigItem::CommitNewItems(WorkQueue& upq, std::vector& newItems) { typedef std::pair ItemPair; std::vector items; @@ -320,6 +333,7 @@ bool ConfigItem::CommitNewItems(WorkQueue& upq) return true; BOOST_FOREACH(const ItemPair& ip, items) { + newItems.push_back(ip.first); upq.Enqueue(boost::bind(&ConfigItem::Commit, ip.first, ip.second)); } @@ -398,7 +412,7 @@ bool ConfigItem::CommitNewItems(WorkQueue& upq) if (upq.HasExceptions()) return false; - if (!CommitNewItems(upq)) + if (!CommitNewItems(upq, newItems)) return false; } } @@ -406,44 +420,53 @@ bool ConfigItem::CommitNewItems(WorkQueue& upq) return true; } -bool ConfigItem::CommitItems(void) +bool ConfigItem::CommitItems(WorkQueue& upq) { - WorkQueue upq(25000, Application::GetConcurrency()); - Log(LogInformation, "ConfigItem", "Committing config items"); - if (!CommitNewItems(upq)) { + std::vector newItems; + + if (!CommitNewItems(upq, newItems)) { upq.ReportExceptions("config"); + + BOOST_FOREACH(const ConfigItem::Ptr& item, newItems) { + item->Unregister(); + } + return false; } ApplyRule::CheckMatches(); /* log stats for external parsers */ - BOOST_FOREACH(const DynamicType::Ptr& type, DynamicType::GetTypes()) { - int count = std::distance(type->GetObjects().first, type->GetObjects().second); - if (count > 0) - Log(LogInformation, "ConfigItem") - << "Checked " << count << " " << type->GetName() << "(s)."; + typedef std::map ItemCountMap; + ItemCountMap itemCounts; + BOOST_FOREACH(const ConfigItem::Ptr& item, newItems) { + itemCounts[item->m_Object->GetReflectionType()]++; + } + + BOOST_FOREACH(const ItemCountMap::value_type& kv, itemCounts) { + Log(LogInformation, "ConfigItem") + << "Instantiated " << kv.second << " " << kv.first->GetPluralName() << "."; } return true; } -bool ConfigItem::ActivateItems(void) +bool ConfigItem::ActivateItems(WorkQueue& upq, bool restoreState) { - /* restore the previous program state */ - try { - DynamicObject::RestoreObjects(Application::GetStatePath()); - } catch (const std::exception& ex) { - Log(LogCritical, "ConfigItem") - << "Failed to restore state file: " << DiagnosticInformation(ex); + if (restoreState) { + /* restore the previous program state */ + try { + DynamicObject::RestoreObjects(Application::GetStatePath()); + } catch (const std::exception& ex) { + Log(LogCritical, "ConfigItem") + << "Failed to restore state file: " << DiagnosticInformation(ex); + } } Log(LogInformation, "ConfigItem", "Triggering Start signal for config items"); - WorkQueue upq(25000, Application::GetConcurrency()); - BOOST_FOREACH(const DynamicType::Ptr& type, DynamicType::GetTypes()) { BOOST_FOREACH(const DynamicObject::Ptr& object, type->GetObjects()) { if (object->IsActive()) @@ -481,40 +504,11 @@ bool ConfigItem::CommitAndActivate(void) { WorkQueue upq(25000, Application::GetConcurrency()); - if (!CommitNewItems(upq)) { - upq.ReportExceptions("ConfigItem"); - - boost::mutex::scoped_lock lock(m_Mutex); - m_Items.clear(); - m_UnnamedItems.clear(); - + if (!CommitItems(upq)) return false; - } - - BOOST_FOREACH(const DynamicType::Ptr& type, DynamicType::GetTypes()) { - BOOST_FOREACH(const DynamicObject::Ptr& object, type->GetObjects()) { - if (object->IsActive()) - continue; - -#ifdef I2_DEBUG - Log(LogDebug, "ConfigItem") - << "Activating object '" << object->GetName() << "' of type '" << object->GetType()->GetName() << "'"; -#endif /* I2_DEBUG */ - upq.Enqueue(boost::bind(&DynamicObject::Activate, object)); - } - } - - upq.Join(); - - if (upq.HasExceptions()) { - upq.ReportExceptions("ConfigItem"); - - boost::mutex::scoped_lock lock(m_Mutex); - m_Items.clear(); - m_UnnamedItems.clear(); + if (!ActivateItems(upq, false)) return false; - } return true; } diff --git a/lib/config/configitem.hpp b/lib/config/configitem.hpp index 4b0309224..8425336de 100644 --- a/lib/config/configitem.hpp +++ b/lib/config/configitem.hpp @@ -55,6 +55,7 @@ public: DynamicObject::Ptr Commit(bool discard = true); void Register(void); + void Unregister(void); DebugInfo GetDebugInfo(void) const; Dictionary::Ptr GetScope(void) const; @@ -64,8 +65,8 @@ public: static ConfigItem::Ptr GetObject(const String& type, const String& name); - static bool CommitItems(void); - static bool ActivateItems(void); + static bool CommitItems(WorkQueue& upq); + static bool ActivateItems(WorkQueue& upq, bool restoreState); static bool CommitAndActivate(void); @@ -97,7 +98,7 @@ private: static ConfigItem::Ptr GetObjectUnlocked(const String& type, const String& name); - static bool CommitNewItems(WorkQueue& upq); + static bool CommitNewItems(WorkQueue& upq, std::vector& newItems); }; } diff --git a/lib/icinga/dependency.cpp b/lib/icinga/dependency.cpp index 28de23d02..fc1545e12 100644 --- a/lib/icinga/dependency.cpp +++ b/lib/icinga/dependency.cpp @@ -23,6 +23,8 @@ #include "base/logger.hpp" #include "base/exception.hpp" #include +#include +#include using namespace icinga; @@ -45,6 +47,27 @@ String DependencyNameComposer::MakeName(const String& shortName, const Object::P return name; } +Dictionary::Ptr DependencyNameComposer::ParseName(const String& name) const +{ + std::vector tokens; + boost::algorithm::split(tokens, name, boost::is_any_of("!")); + + if (tokens.size() < 2) + BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid Dependency name.")); + + Dictionary::Ptr result = new Dictionary(); + result->Set("child_host_name", tokens[0]); + + if (tokens.size() > 2) { + result->Set("child_service_name", tokens[1]); + result->Set("name", tokens[2]); + } else { + result->Set("name", tokens[1]); + } + + return result; +} + void Dependency::OnConfigLoaded(void) { Value defaultFilter; diff --git a/lib/icinga/dependency.ti b/lib/icinga/dependency.ti index 741d3877b..2d7089663 100644 --- a/lib/icinga/dependency.ti +++ b/lib/icinga/dependency.ti @@ -30,6 +30,7 @@ class I2_ICINGA_API DependencyNameComposer : public NameComposer { public: virtual String MakeName(const String& shortName, const Object::Ptr& context) const; + virtual Dictionary::Ptr ParseName(const String& name) const; }; }}} diff --git a/lib/icinga/notification.cpp b/lib/icinga/notification.cpp index 162b3e971..45ba8ba43 100644 --- a/lib/icinga/notification.cpp +++ b/lib/icinga/notification.cpp @@ -29,6 +29,8 @@ #include "base/initialize.hpp" #include "base/scriptglobal.hpp" #include +#include +#include using namespace icinga; @@ -54,6 +56,27 @@ String NotificationNameComposer::MakeName(const String& shortName, const Object: return name; } +Dictionary::Ptr NotificationNameComposer::ParseName(const String& name) const +{ + std::vector tokens; + boost::algorithm::split(tokens, name, boost::is_any_of("!")); + + if (tokens.size() < 2) + BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid Notification name.")); + + Dictionary::Ptr result = new Dictionary(); + result->Set("host_name", tokens[0]); + + if (tokens.size() > 2) { + result->Set("service_name", tokens[1]); + result->Set("name", tokens[2]); + } else { + result->Set("name", tokens[1]); + } + + return result; +} + void Notification::StaticInitialize(void) { ScriptGlobal::Set("OK", StateFilterOK); diff --git a/lib/icinga/notification.ti b/lib/icinga/notification.ti index 4cedb95d1..28c8b4b70 100644 --- a/lib/icinga/notification.ti +++ b/lib/icinga/notification.ti @@ -29,6 +29,7 @@ class I2_ICINGA_API NotificationNameComposer : public NameComposer { public: virtual String MakeName(const String& shortName, const Object::Ptr& context) const; + virtual Dictionary::Ptr ParseName(const String& name) const; }; }}} diff --git a/lib/icinga/scheduleddowntime.cpp b/lib/icinga/scheduleddowntime.cpp index 8428738a5..21d14f477 100644 --- a/lib/icinga/scheduleddowntime.cpp +++ b/lib/icinga/scheduleddowntime.cpp @@ -31,6 +31,8 @@ #include "base/logger.hpp" #include "base/exception.hpp" #include +#include +#include using namespace icinga; @@ -57,6 +59,27 @@ String ScheduledDowntimeNameComposer::MakeName(const String& shortName, const Ob return name; } +Dictionary::Ptr ScheduledDowntimeNameComposer::ParseName(const String& name) const +{ + std::vector tokens; + boost::algorithm::split(tokens, name, boost::is_any_of("!")); + + if (tokens.size() < 2) + BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid ScheduledDowntime name.")); + + Dictionary::Ptr result = new Dictionary(); + result->Set("host_name", tokens[0]); + + if (tokens.size() > 2) { + result->Set("service_name", tokens[1]); + result->Set("name", tokens[2]); + } else { + result->Set("name", tokens[1]); + } + + return result; +} + void ScheduledDowntime::StaticInitialize(void) { l_Timer = new Timer(); diff --git a/lib/icinga/scheduleddowntime.ti b/lib/icinga/scheduleddowntime.ti index 729a0e08d..c41363aeb 100644 --- a/lib/icinga/scheduleddowntime.ti +++ b/lib/icinga/scheduleddowntime.ti @@ -29,6 +29,7 @@ class I2_ICINGA_API ScheduledDowntimeNameComposer : public NameComposer { public: virtual String MakeName(const String& shortName, const Object::Ptr& context) const; + virtual Dictionary::Ptr ParseName(const String& name) const; }; }}} diff --git a/lib/icinga/service.cpp b/lib/icinga/service.cpp index f9e7e915e..aa713a6c0 100644 --- a/lib/icinga/service.cpp +++ b/lib/icinga/service.cpp @@ -27,6 +27,8 @@ #include "base/utility.hpp" #include #include +#include +#include using namespace icinga; @@ -42,6 +44,21 @@ String ServiceNameComposer::MakeName(const String& shortName, const Object::Ptr& return service->GetHostName() + "!" + shortName; } +Dictionary::Ptr ServiceNameComposer::ParseName(const String& name) const +{ + std::vector tokens; + boost::algorithm::split(tokens, name, boost::is_any_of("!")); + + if (tokens.size() < 2) + BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid Service name.")); + + Dictionary::Ptr result = new Dictionary(); + result->Set("host_name", tokens[0]); + result->Set("name", tokens[1]); + + return result; +} + void Service::OnAllConfigLoaded(void) { Checkable::OnAllConfigLoaded(); diff --git a/lib/icinga/service.ti b/lib/icinga/service.ti index 276aa7887..49e96bf55 100644 --- a/lib/icinga/service.ti +++ b/lib/icinga/service.ti @@ -32,6 +32,7 @@ class I2_ICINGA_API ServiceNameComposer : public NameComposer { public: virtual String MakeName(const String& shortName, const Object::Ptr& context) const; + virtual Dictionary::Ptr ParseName(const String& name) const; }; }}} diff --git a/lib/remote/CMakeLists.txt b/lib/remote/CMakeLists.txt index 6791bd12e..1e3b3cbaf 100644 --- a/lib/remote/CMakeLists.txt +++ b/lib/remote/CMakeLists.txt @@ -23,8 +23,8 @@ mkclass_target(zone.ti zone.tcpp zone.thpp) set(remote_SOURCES actionshandler.cpp apiaction.cpp apifunction.cpp apilistener.cpp apilistener.thpp apilistener-sync.cpp - apiuser.cpp apiuser.thpp authority.cpp base64.cpp createobjecthandler.cpp configfileshandler.cpp - configmoduleshandler.cpp configmoduleutility.cpp configstageshandler.cpp + apiuser.cpp apiuser.thpp authority.cpp base64.cpp createobjecthandler.cpp deleteobjecthandler.cpp + configfileshandler.cpp configmoduleshandler.cpp configmoduleutility.cpp configstageshandler.cpp endpoint.cpp endpoint.thpp filterutility.cpp httpchunkedencoding.cpp httpconnection.cpp httphandler.cpp httprequest.cpp httpresponse.cpp httputility.cpp jsonrpc.cpp jsonrpcconnection.cpp jsonrpcconnection-heartbeat.cpp diff --git a/lib/remote/createobjecthandler.cpp b/lib/remote/createobjecthandler.cpp index d535a5e42..a6b568941 100644 --- a/lib/remote/createobjecthandler.cpp +++ b/lib/remote/createobjecthandler.cpp @@ -47,6 +47,14 @@ bool CreateObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r String name = request.RequestUrl->GetPath()[2]; + NameComposer *nc = dynamic_cast(type.get()); + Dictionary::Ptr nameParts; + + if (nc) { + nameParts = nc->ParseName(name); + name = nameParts->Get("name"); + } + Dictionary::Ptr params = HttpUtility::FetchRequestParameters(request); ConfigItemBuilder::Ptr builder = new ConfigItemBuilder(); @@ -64,6 +72,14 @@ bool CreateObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r } } + if (nameParts) { + ObjectLock olock(nameParts); + BOOST_FOREACH(const Dictionary::Pair& kv, nameParts) { + SetExpression *expr = new SetExpression(MakeIndexer(ScopeThis, kv.first), OpSetLiteral, MakeLiteral(kv.second)); + builder->AddExpression(expr); + } + } + Dictionary::Ptr attrs = params->Get("attrs"); if (attrs) { @@ -77,11 +93,28 @@ bool CreateObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r ConfigItem::Ptr item = builder->Compile(); item->Register(); - ConfigItem::CommitAndActivate(); + WorkQueue upq; Dictionary::Ptr result1 = new Dictionary(); - result1->Set("code", 200); - result1->Set("status", "Object created."); + int code; + String status; + + if (!ConfigItem::CommitItems(upq) || !ConfigItem::ActivateItems(upq, false)) { + code = 500; + status = "Object could not be created."; + + Array::Ptr errors = new Array(); + BOOST_FOREACH(const boost::exception_ptr& ex, upq.GetExceptions()) { + errors->Add(DiagnosticInformation(ex)); + } + result1->Set("errors", errors); + } else { + code = 200; + status = "Object created"; + } + + result1->Set("code", code); + result1->Set("status", status); Array::Ptr results = new Array(); results->Add(result1); @@ -89,7 +122,7 @@ bool CreateObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r Dictionary::Ptr result = new Dictionary(); result->Set("results", results); - response.SetStatus(200, "OK"); + response.SetStatus(code, status); HttpUtility::SendJsonBody(response, result); return true; diff --git a/lib/remote/deleteobjecthandler.cpp b/lib/remote/deleteobjecthandler.cpp new file mode 100644 index 000000000..aa21b7933 --- /dev/null +++ b/lib/remote/deleteobjecthandler.cpp @@ -0,0 +1,97 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012-2015 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 "remote/deleteobjecthandler.hpp" +#include "remote/httputility.hpp" +#include "remote/filterutility.hpp" +#include "remote/apiaction.hpp" +#include "config/configitem.hpp" +#include "base/exception.hpp" +#include "base/serializer.hpp" +#include +#include + +using namespace icinga; + +REGISTER_URLHANDLER("/v1", DeleteObjectHandler); + +bool DeleteObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response) +{ + if (request.RequestMethod != "DELETE") + return false; + + if (request.RequestUrl->GetPath().size() < 2) + return false; + + Type::Ptr type = FilterUtility::TypeFromPluralName(request.RequestUrl->GetPath()[1]); + + if (!type) + return false; + + QueryDescription qd; + qd.Types.insert(type); + + Dictionary::Ptr params = HttpUtility::FetchRequestParameters(request); + + params->Set("type", type->GetName()); + + if (request.RequestUrl->GetPath().size() >= 3) { + String attr = type->GetName(); + boost::algorithm::to_lower(attr); + params->Set(attr, request.RequestUrl->GetPath()[2]); + } + + std::vector objs = FilterUtility::GetFilterTargets(qd, params); + + Array::Ptr results = new Array(); + + BOOST_FOREACH(const DynamicObject::Ptr& obj, objs) { + Dictionary::Ptr result1 = new Dictionary(); + result1->Set("type", type->GetName()); + result1->Set("name", obj->GetName()); + + ConfigItem::Ptr item = ConfigItem::GetObject(type->GetName(), obj->GetName()); + + try { + obj->Deactivate(); + + if (item) + item->Unregister(); + else + obj->Unregister(); + + result1->Set("code", 200); + result1->Set("status", "Object was deleted."); + } catch (const std::exception& ex) { + result1->Set("code", 500); + result1->Set("status", "Object could not be deleted: " + DiagnosticInformation(ex)); + } + + results->Add(result1); + } + + Dictionary::Ptr result = new Dictionary(); + result->Set("results", results); + + response.SetStatus(200, "OK"); + HttpUtility::SendJsonBody(response, result); + + return true; +} + diff --git a/lib/remote/deleteobjecthandler.hpp b/lib/remote/deleteobjecthandler.hpp new file mode 100644 index 000000000..ec35e9d64 --- /dev/null +++ b/lib/remote/deleteobjecthandler.hpp @@ -0,0 +1,38 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012-2015 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 DELETEOBJECTHANDLER_H +#define DELETEOBJECTHANDLER_H + +#include "remote/httphandler.hpp" + +namespace icinga +{ + +class I2_REMOTE_API DeleteObjectHandler : public HttpHandler +{ +public: + DECLARE_PTR_TYPEDEFS(DeleteObjectHandler); + + virtual bool HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response); +}; + +} + +#endif /* DELETEOBJECTHANDLER_H */ diff --git a/lib/remote/filterutility.cpp b/lib/remote/filterutility.cpp index 2764b2c0e..143939b56 100644 --- a/lib/remote/filterutility.cpp +++ b/lib/remote/filterutility.cpp @@ -38,7 +38,7 @@ Type::Ptr FilterUtility::TypeFromPluralName(const String& pluralName) Type::Ptr type = Type::GetByName(dtype->GetName()); ASSERT(type); - String pname = GetPluralName(type); + String pname = type->GetPluralName(); boost::algorithm::to_lower(pname); if (uname == pname) @@ -48,16 +48,6 @@ Type::Ptr FilterUtility::TypeFromPluralName(const String& pluralName) return Type::Ptr(); } -String FilterUtility::GetPluralName(const Type::Ptr& type) -{ - String name = type->GetName(); - - if (name[name.GetLength() - 1] == 'y') - return name.SubStr(0, name.GetLength() - 1) + "ies"; - else - return name + "s"; -} - DynamicObject::Ptr FilterUtility::GetObjectByTypeAndName(const String& type, const String& name) { DynamicType::Ptr dtype = DynamicType::GetByName(type); @@ -82,7 +72,7 @@ std::vector FilterUtility::GetFilterTargets(const QueryDescr result.push_back(obj); } - attr = GetPluralName(type); + attr = type->GetPluralName(); boost::algorithm::to_lower(attr); if (query->Contains(attr)) { diff --git a/lib/remote/filterutility.hpp b/lib/remote/filterutility.hpp index b7c28821d..42a3d2760 100644 --- a/lib/remote/filterutility.hpp +++ b/lib/remote/filterutility.hpp @@ -41,7 +41,6 @@ struct QueryDescription class I2_REMOTE_API FilterUtility { public: - static String GetPluralName(const Type::Ptr& type); static Type::Ptr TypeFromPluralName(const String& pluralName); static DynamicObject::Ptr GetObjectByTypeAndName(const String& type, const String& name); static std::vector GetFilterTargets(const QueryDescription& qd, const Dictionary::Ptr& query); diff --git a/lib/remote/modifyobjecthandler.cpp b/lib/remote/modifyobjecthandler.cpp index 842a30a96..296392261 100644 --- a/lib/remote/modifyobjecthandler.cpp +++ b/lib/remote/modifyobjecthandler.cpp @@ -65,7 +65,7 @@ bool ModifyObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r BOOST_FOREACH(const DynamicObject::Ptr& obj, objs) { Dictionary::Ptr result1 = new Dictionary(); - result1->Set("type", obj->GetReflectionType()->GetName()); + result1->Set("type", type->GetName()); result1->Set("name", obj->GetName()); String key; diff --git a/test/livestatus.cpp b/test/livestatus.cpp index f876eb577..b59876c5e 100644 --- a/test/livestatus.cpp +++ b/test/livestatus.cpp @@ -87,7 +87,8 @@ struct GlobalConfigFixture { DaemonUtility::LoadConfigFiles(configs, "icinga2.debug", "icinga2.vars"); /* ignore config errors */ - ConfigItem::ActivateItems(); + WorkQueue upq; + ConfigItem::ActivateItems(upq, false); } ~GlobalConfigFixture()