mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-23 13:45:04 +02:00
Refactor ObjectQueryHandler to use new JSON stream encoder
This commit is contained in:
parent
749a4b0c89
commit
fcad7f77cc
@ -1,6 +1,8 @@
|
|||||||
/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
|
/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
|
||||||
|
|
||||||
#include "remote/objectqueryhandler.hpp"
|
#include "remote/objectqueryhandler.hpp"
|
||||||
|
#include "base/generator.hpp"
|
||||||
|
#include "base/json.hpp"
|
||||||
#include "remote/httputility.hpp"
|
#include "remote/httputility.hpp"
|
||||||
#include "remote/filterutility.hpp"
|
#include "remote/filterutility.hpp"
|
||||||
#include "base/serializer.hpp"
|
#include "base/serializer.hpp"
|
||||||
@ -9,6 +11,7 @@
|
|||||||
#include <boost/algorithm/string/case_conv.hpp>
|
#include <boost/algorithm/string/case_conv.hpp>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
@ -140,6 +143,16 @@ bool ObjectQueryHandler::HandleRequest(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(umetas){
|
||||||
|
ObjectLock olock(umetas);
|
||||||
|
for (String meta : umetas) {
|
||||||
|
if (!(meta == "used_by" || meta == "location")) {
|
||||||
|
response.SendJsonError(request.Params(), 400, "Invalid field specified for meta: " + meta);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool allJoins = request.GetLastParameter("all_joins");
|
bool allJoins = request.GetLastParameter("all_joins");
|
||||||
|
|
||||||
request.Params()->Set("type", type->GetName());
|
request.Params()->Set("type", type->GetName());
|
||||||
@ -161,9 +174,6 @@ bool ObjectQueryHandler::HandleRequest(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayData results;
|
|
||||||
results.reserve(objs.size());
|
|
||||||
|
|
||||||
std::set<String> joinAttrs;
|
std::set<String> joinAttrs;
|
||||||
std::set<String> userJoinAttrs;
|
std::set<String> userJoinAttrs;
|
||||||
|
|
||||||
@ -189,14 +199,21 @@ bool ObjectQueryHandler::HandleRequest(
|
|||||||
std::unordered_map<Type*, std::pair<bool, std::unique_ptr<Expression>>> typePermissions;
|
std::unordered_map<Type*, std::pair<bool, std::unique_ptr<Expression>>> typePermissions;
|
||||||
std::unordered_map<Object*, bool> objectAccessAllowed;
|
std::unordered_map<Object*, bool> objectAccessAllowed;
|
||||||
|
|
||||||
for (ConfigObject::Ptr obj : objs) {
|
auto it = objs.begin();
|
||||||
|
auto generatorFunc = [&]() -> std::optional<Value> {
|
||||||
|
if (it == objs.end()) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigObject::Ptr obj = *it;
|
||||||
|
++it;
|
||||||
|
|
||||||
DictionaryData result1{
|
DictionaryData result1{
|
||||||
{ "name", obj->GetName() },
|
{ "name", obj->GetName() },
|
||||||
{ "type", obj->GetReflectionType()->GetName() }
|
{ "type", obj->GetReflectionType()->GetName() }
|
||||||
};
|
};
|
||||||
|
|
||||||
DictionaryData metaAttrs;
|
DictionaryData metaAttrs;
|
||||||
|
|
||||||
if (umetas) {
|
if (umetas) {
|
||||||
ObjectLock olock(umetas);
|
ObjectLock olock(umetas);
|
||||||
for (String meta : umetas) {
|
for (String meta : umetas) {
|
||||||
@ -212,9 +229,6 @@ bool ObjectQueryHandler::HandleRequest(
|
|||||||
}
|
}
|
||||||
} else if (meta == "location") {
|
} else if (meta == "location") {
|
||||||
metaAttrs.emplace_back("location", obj->GetSourceLocation());
|
metaAttrs.emplace_back("location", obj->GetSourceLocation());
|
||||||
} else {
|
|
||||||
response.SendJsonError(request.Params(), 400, "Invalid field specified for meta: " + meta);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,8 +238,12 @@ bool ObjectQueryHandler::HandleRequest(
|
|||||||
try {
|
try {
|
||||||
result1.emplace_back("attrs", SerializeObjectAttrs(obj, String(), uattrs, false, false));
|
result1.emplace_back("attrs", SerializeObjectAttrs(obj, String(), uattrs, false, false));
|
||||||
} catch (const ScriptError& ex) {
|
} catch (const ScriptError& ex) {
|
||||||
response.SendJsonError(request.Params(), 400, ex.what());
|
return new Dictionary{
|
||||||
return true;
|
{"type", type->GetName()},
|
||||||
|
{"name", obj->GetName()},
|
||||||
|
{"code", 400},
|
||||||
|
{"status", ex.what()}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
DictionaryData joins;
|
DictionaryData joins;
|
||||||
@ -234,18 +252,8 @@ bool ObjectQueryHandler::HandleRequest(
|
|||||||
Object::Ptr joinedObj;
|
Object::Ptr joinedObj;
|
||||||
int fid = type->GetFieldId(joinAttr);
|
int fid = type->GetFieldId(joinAttr);
|
||||||
|
|
||||||
if (fid < 0) {
|
|
||||||
response.SendJsonError(request.Params(), 400, "Invalid field specified for join: " + joinAttr);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Field field = type->GetFieldInfo(fid);
|
Field field = type->GetFieldInfo(fid);
|
||||||
|
|
||||||
if (!(field.Attributes & FANavigation)) {
|
|
||||||
response.SendJsonError(request.Params(), 400, "Not a joinable field: " + joinAttr);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
joinedObj = obj->NavigateField(fid);
|
joinedObj = obj->NavigateField(fid);
|
||||||
|
|
||||||
if (!joinedObj)
|
if (!joinedObj)
|
||||||
@ -299,22 +307,30 @@ bool ObjectQueryHandler::HandleRequest(
|
|||||||
try {
|
try {
|
||||||
joins.emplace_back(prefix, SerializeObjectAttrs(joinedObj, prefix, ujoins, true, allJoins));
|
joins.emplace_back(prefix, SerializeObjectAttrs(joinedObj, prefix, ujoins, true, allJoins));
|
||||||
} catch (const ScriptError& ex) {
|
} catch (const ScriptError& ex) {
|
||||||
response.SendJsonError(request.Params(), 400, ex.what());
|
return new Dictionary{
|
||||||
return true;
|
{"type", type->GetName()},
|
||||||
|
{"name", obj->GetName()},
|
||||||
|
{"code", 400},
|
||||||
|
{"status", ex.what()}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result1.emplace_back("joins", new Dictionary(std::move(joins)));
|
result1.emplace_back("joins", new Dictionary(std::move(joins)));
|
||||||
|
|
||||||
results.push_back(new Dictionary(std::move(result1)));
|
return new Dictionary{std::move(result1)};
|
||||||
}
|
};
|
||||||
|
|
||||||
Dictionary::Ptr result = new Dictionary({
|
|
||||||
{ "results", new Array(std::move(results)) }
|
|
||||||
});
|
|
||||||
|
|
||||||
response.result(http::status::ok);
|
response.result(http::status::ok);
|
||||||
response.SendJsonBody(request.Params(), result);
|
response.set(http::field::content_type, "application/json");
|
||||||
|
response.StartStreaming();
|
||||||
|
|
||||||
|
Dictionary::Ptr results = new Dictionary{{"results", new ValueGenerator{generatorFunc}}};
|
||||||
|
results->Freeze();
|
||||||
|
|
||||||
|
auto adapter = std::make_shared<BeastHttpMessageAdapter<HttpResponse>>(response);
|
||||||
|
JsonEncoder encoder(adapter, request.IsPretty());
|
||||||
|
encoder.Encode(results, &yc);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user