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+ */
|
||||
|
||||
#include "remote/objectqueryhandler.hpp"
|
||||
#include "base/generator.hpp"
|
||||
#include "base/json.hpp"
|
||||
#include "remote/httputility.hpp"
|
||||
#include "remote/filterutility.hpp"
|
||||
#include "base/serializer.hpp"
|
||||
@ -9,6 +11,7 @@
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
@ -140,6 +143,16 @@ bool ObjectQueryHandler::HandleRequest(
|
||||
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");
|
||||
|
||||
request.Params()->Set("type", type->GetName());
|
||||
@ -161,9 +174,6 @@ bool ObjectQueryHandler::HandleRequest(
|
||||
return true;
|
||||
}
|
||||
|
||||
ArrayData results;
|
||||
results.reserve(objs.size());
|
||||
|
||||
std::set<String> joinAttrs;
|
||||
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<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{
|
||||
{ "name", obj->GetName() },
|
||||
{ "type", obj->GetReflectionType()->GetName() }
|
||||
};
|
||||
|
||||
DictionaryData metaAttrs;
|
||||
|
||||
if (umetas) {
|
||||
ObjectLock olock(umetas);
|
||||
for (String meta : umetas) {
|
||||
@ -212,9 +229,6 @@ bool ObjectQueryHandler::HandleRequest(
|
||||
}
|
||||
} else if (meta == "location") {
|
||||
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 {
|
||||
result1.emplace_back("attrs", SerializeObjectAttrs(obj, String(), uattrs, false, false));
|
||||
} catch (const ScriptError& ex) {
|
||||
response.SendJsonError(request.Params(), 400, ex.what());
|
||||
return true;
|
||||
return new Dictionary{
|
||||
{"type", type->GetName()},
|
||||
{"name", obj->GetName()},
|
||||
{"code", 400},
|
||||
{"status", ex.what()}
|
||||
};
|
||||
}
|
||||
|
||||
DictionaryData joins;
|
||||
@ -234,18 +252,8 @@ bool ObjectQueryHandler::HandleRequest(
|
||||
Object::Ptr joinedObj;
|
||||
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);
|
||||
|
||||
if (!(field.Attributes & FANavigation)) {
|
||||
response.SendJsonError(request.Params(), 400, "Not a joinable field: " + joinAttr);
|
||||
return true;
|
||||
}
|
||||
|
||||
joinedObj = obj->NavigateField(fid);
|
||||
|
||||
if (!joinedObj)
|
||||
@ -299,22 +307,30 @@ bool ObjectQueryHandler::HandleRequest(
|
||||
try {
|
||||
joins.emplace_back(prefix, SerializeObjectAttrs(joinedObj, prefix, ujoins, true, allJoins));
|
||||
} catch (const ScriptError& ex) {
|
||||
response.SendJsonError(request.Params(), 400, ex.what());
|
||||
return true;
|
||||
return new Dictionary{
|
||||
{"type", type->GetName()},
|
||||
{"name", obj->GetName()},
|
||||
{"code", 400},
|
||||
{"status", ex.what()}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
result1.emplace_back("joins", new Dictionary(std::move(joins)));
|
||||
|
||||
results.push_back(new Dictionary(std::move(result1)));
|
||||
}
|
||||
|
||||
Dictionary::Ptr result = new Dictionary({
|
||||
{ "results", new Array(std::move(results)) }
|
||||
});
|
||||
return new Dictionary{std::move(result1)};
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user