Skip to content

Commit 8d7cf22

Browse files
committed
Enable retrieving basic/full tree
Re ECFLOW-1939
1 parent 923661a commit 8d7cf22

13 files changed

+559
-35
lines changed

ACore/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ set(srcs
4343
src/ecflow/core/NOrder.hpp
4444
src/ecflow/core/NState.hpp
4545
src/ecflow/core/NodePath.hpp
46+
src/ecflow/core/Overload.hpp
4647
src/ecflow/core/Passwd.hpp
4748
src/ecflow/core/PasswdFile.hpp
4849
src/ecflow/core/PasswordEncryption.hpp

ACore/src/ecflow/core/Overload.hpp

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright 2009- ECMWF.
3+
*
4+
* This software is licensed under the terms of the Apache Licence version 2.0
5+
* which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6+
* In applying this licence, ECMWF does not waive the privileges and immunities
7+
* granted to it by virtue of its status as an intergovernmental organisation
8+
* nor does it submit to any jurisdiction.
9+
*/
10+
11+
#ifndef ecflow_core_Overload_HPP
12+
#define ecflow_core_Overload_HPP
13+
14+
namespace ecf {
15+
16+
template <class... Ts>
17+
struct overload : Ts...
18+
{
19+
using Ts::operator()...;
20+
};
21+
22+
template <class... Ts>
23+
overload(Ts...) -> overload<Ts...>; // Deduction guideline not needed from C++20
24+
25+
} // namespace ecf
26+
27+
#endif /* ecflow_core_Overload_HPP */

ANode/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ set(srcs
2020
src/ecflow/node/CmdContext.hpp
2121
src/ecflow/node/Defs.hpp
2222
src/ecflow/node/DefsDelta.hpp
23+
src/ecflow/node/DefsTreeVisitor.hpp
2324
src/ecflow/node/EcfFile.hpp
2425
src/ecflow/node/ExprAst.hpp
2526
src/ecflow/node/ExprAstVisitor.hpp
+132
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
/*
2+
* Copyright 2009- ECMWF.
3+
*
4+
* This software is licensed under the terms of the Apache Licence version 2.0
5+
* which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6+
* In applying this licence, ECMWF does not waive the privileges and immunities
7+
* granted to it by virtue of its status as an intergovernmental organisation
8+
* nor does it submit to any jurisdiction.
9+
*/
10+
11+
#ifndef ecflow_node_DefsTreeVisitor_HPP
12+
#define ecflow_node_DefsTreeVisitor_HPP
13+
14+
#include <string>
15+
#include <vector>
16+
17+
#include <ecflow/node/Alias.hpp>
18+
#include <ecflow/node/Defs.hpp>
19+
#include <ecflow/node/Family.hpp>
20+
#include <ecflow/node/Node.hpp>
21+
#include <ecflow/node/Suite.hpp>
22+
#include <ecflow/node/Task.hpp>
23+
24+
namespace ecf {
25+
26+
struct NodeNotFound : public std::runtime_error
27+
{
28+
using std::runtime_error::runtime_error;
29+
};
30+
31+
template <typename V>
32+
struct DefsTreeVisitor
33+
{
34+
using path_t = std::string;
35+
using nodes_t = std::vector<const Node*>;
36+
37+
DefsTreeVisitor(const defs_ptr& defs, V& v) : defs_{*defs}, v_{v} {}
38+
39+
DefsTreeVisitor(const Defs& defs, V& v) : defs_{defs}, v_{v} {}
40+
41+
void visit_at(const path_t& path) {
42+
nodes_t nodes = nodes_at(path);
43+
for (auto node : nodes) {
44+
visit(*node);
45+
}
46+
}
47+
48+
private:
49+
const Defs& defs_;
50+
V& v_;
51+
52+
private:
53+
nodes_t nodes_at(const path_t& path) const {
54+
nodes_t nodes;
55+
if (path == "/") {
56+
std::vector<suite_ptr> suites = defs_.suiteVec();
57+
std::transform(std::begin(suites), std::end(suites), std::back_inserter(nodes), [](const suite_ptr& ptr) {
58+
return static_cast<Node*>(ptr.get());
59+
});
60+
}
61+
else {
62+
nodes = nodes_t{get_node(path).get()};
63+
}
64+
return nodes;
65+
}
66+
67+
node_ptr get_node(const std::string& path) const {
68+
if (node_ptr node = defs_.findAbsNode(path); node) {
69+
return node;
70+
}
71+
72+
throw NodeNotFound(std::string{"Unable to find node: "} + path);
73+
}
74+
75+
void visit(const Node& node) {
76+
77+
if (auto found = dynamic_cast<const Suite*>(&node); found) {
78+
// Visit suite itself
79+
v_.begin_visit(*found);
80+
// Visit suite children
81+
for (auto&& entry : found->nodeVec()) {
82+
visit(*entry.get());
83+
}
84+
v_.end_visit(*found);
85+
return;
86+
}
87+
88+
if (auto found = dynamic_cast<const Family*>(&node); found) {
89+
// Visit family itself
90+
v_.begin_visit(*found);
91+
// Visit family children
92+
for (auto&& entry : found->nodeVec()) {
93+
visit(*entry.get());
94+
}
95+
v_.end_visit(*found);
96+
return;
97+
}
98+
99+
if (auto found = dynamic_cast<const Task*>(&node); found) {
100+
// Visit task itself
101+
v_.begin_visit(*found);
102+
// Visit task children (i.e. aliases)
103+
std::vector<alias_ptr> aliases;
104+
found->get_all_aliases(aliases);
105+
for (const auto& entry : aliases) {
106+
visit(*entry.get());
107+
}
108+
v_.end_visit(*found);
109+
return;
110+
}
111+
112+
if (auto found = dynamic_cast<const Alias*>(&node); found) {
113+
// Visit alias itself
114+
v_.begin_visit(*found);
115+
v_.end_visit(*found);
116+
return;
117+
}
118+
119+
// Important!
120+
// If this point is reached, then some kind of Node isn't being properly handled.
121+
panic();
122+
}
123+
124+
static void panic() {
125+
assert(false);
126+
std::terminate();
127+
}
128+
};
129+
130+
} // namespace ecf
131+
132+
#endif /* ecflow_node_DefsTreeVisitor_HPP */

Http/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ set(srcs
3434
src/ecflow/http/JSON.hpp
3535
src/ecflow/http/Options.hpp
3636
$<$<BOOL:${OPENSSL_FOUND}>:src/ecflow/http/TokenStorage.hpp>
37+
src/ecflow/http/TreeGeneration.hpp
3738
src/ecflow/http/TypeToJson.hpp
3839
# Sources
3940
src/ecflow/http/Api.cpp

Http/src/ecflow/http/Api.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
#include "ecflow/http/Api.hpp"
1212

1313
#include "ecflow/http/ApiV1.hpp"
14-
#include "ecflow/http/Options.hpp"
1514
#include "ecflow/http/DefsStorage.hpp"
15+
#include "ecflow/http/Options.hpp"
1616

1717
namespace ecf::http {
1818

Http/src/ecflow/http/ApiV1.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,11 @@ ojson filter_json(const ojson& j, const httplib::Request& r) {
207207
return dive(j, path_elems);
208208
}
209209

210+
static std::string get_tree_content_kind(const httplib::Request& request) {
211+
constexpr const char* content = "content";
212+
return request.has_param(content) ? request.get_param_value(content) : "basic";
213+
}
214+
210215
} // namespace
211216

212217
namespace v1 {
@@ -256,7 +261,9 @@ void node_tree_read(const httplib::Request& request, httplib::Response& response
256261
trycatch(request, response, [&]() {
257262
num_cached_requests++;
258263
const std::string path = request.matches[1];
259-
ojson j = filter_json(get_sparser_node_tree(path), request);
264+
std::string tree_kind = get_tree_content_kind(request);
265+
ojson tree_content = (tree_kind == "full") ? get_full_node_tree(path) : get_basic_node_tree(path);
266+
ojson j = filter_json(tree_content, request);
260267
response.status = HttpStatusCode::success_ok;
261268
response.set_content(j.dump(), "application/json");
262269
set_cors(response);

Http/src/ecflow/http/ApiV1Impl.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515

1616
#include "ecflow/core/Child.hpp"
1717
#include "ecflow/core/Converter.hpp"
18+
#include "ecflow/core/DState.hpp"
19+
#include "ecflow/core/NState.hpp"
20+
#include "ecflow/core/Overload.hpp"
1821
#include "ecflow/core/Str.hpp"
1922
#include "ecflow/http/BasicAuth.hpp"
2023
#include "ecflow/http/Client.hpp"
@@ -25,11 +28,15 @@
2528
#endif
2629
#include "ecflow/http/DefsStorage.hpp"
2730
#include "ecflow/http/HttpLibrary.hpp"
31+
#include "ecflow/http/TreeGeneration.hpp"
2832
#include "ecflow/http/TypeToJson.hpp"
33+
#include "ecflow/node/Alias.hpp"
2934
#include "ecflow/node/Defs.hpp"
35+
#include "ecflow/node/DefsTreeVisitor.hpp"
3036
#include "ecflow/node/Family.hpp"
3137
#include "ecflow/node/Limit.hpp"
3238
#include "ecflow/node/Suite.hpp"
39+
#include "ecflow/node/Task.hpp"
3340
#include "ecflow/node/parser/DefsStructureParser.hpp"
3441

3542
// For token based authentication, this user account
@@ -116,6 +123,18 @@ void apply_to_parents(const Node* node, T&& func) {
116123
}
117124
}
118125

126+
ojson get_basic_node_tree(const std::string& path) {
127+
BasicTree tree;
128+
DefsTreeVisitor(get_defs(), tree).visit_at(path);
129+
return tree.content();
130+
}
131+
132+
ojson get_full_node_tree(const std::string& path) {
133+
FullTree tree;
134+
DefsTreeVisitor(get_defs(), tree).visit_at(path);
135+
return tree.content();
136+
}
137+
119138
ojson get_sparser_node_tree(const std::string& path) {
120139
ojson j;
121140

Http/src/ecflow/http/ApiV1Impl.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
namespace ecf::http {
1919

20+
ojson get_basic_node_tree(const std::string& path);
21+
ojson get_full_node_tree(const std::string& path);
2022
ojson get_sparser_node_tree(const std::string& path);
2123

2224
void add_suite(const httplib::Request& request, httplib::Response& response);

0 commit comments

Comments
 (0)