1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-09 00:00:00 +01:00

No not pass super-node UUID to Node::parse() any longer

Signed-off-by: Steffen Vogel <steffen.vogel@opal-rt.com>
This commit is contained in:
Steffen Vogel 2023-06-30 10:51:01 +02:00
parent d57a5d3306
commit 7749a3a922
28 changed files with 136 additions and 143 deletions

View file

@ -16,7 +16,7 @@
typedef void *vnode;
typedef void *vsample;
vnode * node_new(const char *json_str, const char *sn_uuid_str);
vnode * node_new(const char *id_str, const char *json_str);
int node_prepare(vnode *n);

View file

@ -18,6 +18,7 @@
#include <villas/sample.hpp>
#include <villas/list.hpp>
#include <villas/queue.h>
#include <villas/colors.hpp>
#include <villas/common.hpp>
#include <villas/stats.hpp>
#include <villas/log.hpp>
@ -107,7 +108,7 @@ protected:
public:
/** Initialize node with default values */
Node(const std::string &name = "");
Node(const uuid_t &id = {}, const std::string &name = "");
/** Destroy node by freeing dynamically allocated memory. */
virtual
@ -124,7 +125,7 @@ public:
* @retval <0 Error. Something went wrong.
*/
virtual
int parse(json_t *json, const uuid_t sn_uuid);
int parse(json_t *json);
/** Validate node configuration. */
virtual
@ -351,6 +352,8 @@ protected:
n->logger = getLogger();
n->factory = this;
n->name_long = fmt::format(CLR_RED("{}") "(" CLR_YEL("{}") ")", n->name_short, getName());
instances.push_back(n);
}
@ -376,13 +379,13 @@ public:
}
virtual
Node * make() = 0;
Node * make(const uuid_t &id = {}, const std::string &nme = "") = 0;
static
Node * make(json_t *json, uuid_t uuid);
Node * make(json_t *json, const uuid_t &id, const std::string &name = "");
static
Node * make(const std::string &type);
Node * make(const std::string &type, const uuid_t &id = {}, const std::string &name = "");
virtual
std::string getType() const
@ -438,9 +441,9 @@ class NodePlugin : public NodeFactory {
public:
virtual
Node * make()
Node * make(const uuid_t &id = {}, const std::string &nme = "")
{
T* n = new T();
T* n = new T(id, nme);
init(n);

View file

@ -43,7 +43,7 @@ public:
NodeCompat *node;
json_t *cfg;
NodeCompat(struct NodeCompatType *vt);
NodeCompat(struct NodeCompatType *vt, const uuid_t &id, const std::string &name);
NodeCompat(const NodeCompat& n);
NodeCompat& operator=(const NodeCompat& other);
@ -71,7 +71,7 @@ public:
* @retval <0 Error. Something went wrong.
*/
virtual
int parse(json_t *json, const uuid_t sn_uuid);
int parse(json_t *json);
/** Returns a string with a textual represenation of this node. */
virtual
@ -170,7 +170,7 @@ public:
{ }
virtual
Node * make();
Node * make(const uuid_t &id = {}, const std::string &name = "");
/// Get plugin name
virtual

View file

@ -22,7 +22,7 @@ struct Sample;
class APINode : public Node {
public:
APINode(const std::string &name = "");
APINode(const uuid_t &id = {}, const std::string &name = "");
struct Direction {
Sample *sample;
@ -42,7 +42,7 @@ public:
protected:
virtual
int parse(json_t *json, const uuid_t sn_uuid);
int parse(json_t *json);
virtual
int _read(struct Sample *smps[], unsigned cnt);

View file

@ -42,7 +42,7 @@ protected:
int _write(struct Sample *smps[], unsigned cnt);
public:
ExampleNode(const std::string &name = "");
ExampleNode(const uuid_t &id = {}, const std::string &name = "");
/* All of the following virtual-declared functions are optional.
* Have a look at node.hpp/node.cpp for the default behaviour.
@ -55,7 +55,7 @@ public:
int prepare();
virtual
int parse(json_t *json, const uuid_t sn_uuid);
int parse(json_t *json);
/** Validate node configuration. */
virtual

View file

@ -42,8 +42,8 @@ protected:
int _write(struct Sample * smps[], unsigned cnt);
public:
ExecNode(const std::string &name = "") :
Node(name),
ExecNode(const uuid_t &id = {}, const std::string &name = "") :
Node(id, name),
stream_in(nullptr),
stream_out(nullptr),
flush(true),
@ -66,7 +66,7 @@ public:
int prepare();
virtual
int parse(json_t *json, const uuid_t sn_uuid);
int parse(json_t *json);
virtual
std::vector<int> getPollFDs();

View file

@ -57,7 +57,7 @@ public:
~FpgaNode();
virtual
int parse(json_t *json, const uuid_t sn_uuid);
int parse(json_t *json);
virtual
const std::string & getDetails();

View file

@ -42,7 +42,7 @@ public:
~GoNode();
virtual
int parse(json_t *json, const uuid_t sn_uuid);
int parse(json_t *json);
virtual
std::vector<int> getPollFDs();

View file

@ -171,13 +171,13 @@ protected:
int _write(struct Sample *smps[], unsigned cnt) override;
public:
SlaveNode(const std::string &name = "");
SlaveNode(const uuid_t &id = {}, const std::string &name = "");
virtual
~SlaveNode() override;
virtual
int parse(json_t *json, const uuid_t sn_uuid) override;
int parse(json_t *json) override;
virtual
int start() override;

View file

@ -233,7 +233,7 @@ protected:
int _write(struct Sample *smps[], unsigned cnt) override;
public:
GooseNode(const std::string &name = "");
GooseNode(const uuid_t &id = {}, const std::string &name = "");
virtual
~GooseNode() override;
@ -242,7 +242,7 @@ public:
std::vector<int> getPollFDs() override;
virtual
int parse(json_t *json, const uuid_t sn_uuid) override;
int parse(json_t *json) override;
virtual
int prepare() override;

View file

@ -29,7 +29,7 @@ protected:
int _read(struct Sample * smps[], unsigned cnt);
public:
LoopbackNode(const std::string &name = "");
LoopbackNode(const uuid_t &id = {}, const std::string &name = "");
virtual
~LoopbackNode();

View file

@ -47,7 +47,7 @@ public:
using NodeFactory::NodeFactory;
virtual
Node * make()
Node * make(const uuid_t &id = {}, const std::string &name = "")
{
return nullptr;
}

View file

@ -82,13 +82,13 @@ protected:
int _read(struct Sample *smps[], unsigned cnt);
public:
SignalNode(const std::string &name = "");
SignalNode(const uuid_t &id = {}, const std::string &name = "");
virtual
const std::string & getDetails();
virtual
int parse(json_t *json, const uuid_t sn_uuid);
int parse(json_t *json);
virtual
int start();

View file

@ -48,7 +48,7 @@ protected:
int _write(struct Sample *smps[], unsigned cnt);
public:
WebRTCNode(const std::string &name = "");
WebRTCNode(const uuid_t &id = {}, const std::string &name = "");
virtual
~WebRTCNode();
@ -57,7 +57,7 @@ public:
int prepare();
virtual
int parse(json_t *json, const uuid_t sn_uuid);
int parse(json_t *json);
virtual
int check();
@ -82,9 +82,9 @@ public:
using NodeFactory::NodeFactory;
virtual
Node * make()
Node * make(const uuid_t &id = {}, const std::string &nme = "")
{
auto *n = new WebRTCNode();
auto *n = new WebRTCNode(id, nme);
init(n);

View file

@ -41,7 +41,7 @@ using namespace villas;
using namespace villas::node;
using namespace villas::utils;
Node::Node(const std::string &n) :
Node::Node(const uuid_t &id, const std::string &name) :
logger(logging.get("node")),
sequence_init(0),
sequence(0),
@ -57,14 +57,23 @@ Node::Node(const std::string &n) :
state(State::INITIALIZED),
enabled(true),
config(nullptr),
name_short(n),
name_long(),
name_short(name),
affinity(-1), /* all cores */
factory(nullptr)
{
uuid_clear(uuid);
if (uuid_is_null(id)) {
uuid_generate_random(uuid);
} else {
uuid_copy(uuid, id);
}
name_long = fmt::format(CLR_RED("{}"), n);
if (!name_short.empty()) {
name_long = fmt::format(CLR_RED("{}"), name_short);
}
else if (name_short.empty()) {
name_short = "<none>";
name_long = CLR_RED("<none>");
}
}
Node::~Node()
@ -94,7 +103,7 @@ int Node::prepare()
return 0;
}
int Node::parse(json_t *json, const uuid_t sn_uuid)
int Node::parse(json_t *json)
{
assert(state == State::INITIALIZED ||
state == State::PARSED ||
@ -105,12 +114,7 @@ int Node::parse(json_t *json, const uuid_t sn_uuid)
json_error_t err;
json_t *json_netem = nullptr;
const char *uuid_str = nullptr;
const char *name_str = nullptr;
ret = json_unpack_ex(json, &err, 0, "{ s?: s, s?: s, s?: b, s?: i }",
"name", &name_str,
"uuid", &uuid_str,
ret = json_unpack_ex(json, &err, 0, "{ s?: b, s?: i }",
"enabled", &en,
"initial_sequenceno", &init_seq
);
@ -120,9 +124,6 @@ int Node::parse(json_t *json, const uuid_t sn_uuid)
if (init_seq >= 0)
sequence_init = init_seq;
if (name_str)
logger = logging.get(fmt::format("node:{}", name_str));
#ifdef __linux__
ret = json_unpack_ex(json, &err, 0, "{ s?: { s?: o, s?: i } }",
"out",
@ -135,24 +136,6 @@ int Node::parse(json_t *json, const uuid_t sn_uuid)
enabled = en;
if (name_str) {
name_short = std::string(name_str);
name_long = fmt::format(CLR_RED("{}") "(" CLR_YEL("{}") ")", name_str, factory->getName());
}
else if (name_short.empty()) {
name_short = "<none>";
name_long = CLR_RED("<none>");
}
if (uuid_str) {
ret = uuid_parse(uuid_str, uuid);
if (ret)
throw ConfigError(json, "node-config-node-uuid", "Failed to parse UUID: {}", uuid_str);
}
else
/* Generate UUID from hashed config including node name */
uuid::generateFromJson(uuid, json, sn_uuid);
if (json_netem) {
#ifdef WITH_NETEM
int enabled = 1;
@ -184,7 +167,6 @@ int Node::parse(json_t *json, const uuid_t sn_uuid)
/* Skip if direction is unused */
if (!json_dir) {
json_dir = json_pack("{ s: b }", "enabled", 0);
// json_object_set_new(json, dirs[j].str, json_dir);
}
/* Copy missing fields from main node config to direction config */
@ -492,45 +474,39 @@ void Node::swapSignals() {
SWAP(in.signals, out.signals);
}
Node * NodeFactory::make(json_t *json, uuid_t uuid)
Node * NodeFactory::make(json_t *json, const uuid_t &id, const std::string &name)
{
int ret;
std::string type;
Node *n;
if (json_is_string(json)) {
type = json_string_value(json);
if (json_is_object(json))
throw ConfigError(json, "node-config-node", "Node configuration must be an object");
return NodeFactory::make(type);
json_t *json_type = json_object_get(json, "type");
type = json_string_value(json_type);
n = NodeFactory::make(type, id, name);
if (!n)
return nullptr;
ret = n->parse(json);
if (ret) {
delete n;
return nullptr;
}
else if (json_is_object(json)) {
json_t *json_type = json_object_get(json, "type");
type = json_string_value(json_type);
n = NodeFactory::make(type);
if (!n)
return nullptr;
ret = n->parse(json, uuid);
if (ret) {
delete n;
return nullptr;
}
return n;
}
else
throw ConfigError(json, "node-config-node", "Invalid node config");
return n;
}
Node * NodeFactory::make(const std::string &type)
Node * NodeFactory::make(const std::string &type, const uuid_t &id, const std::string &name)
{
NodeFactory *nf = plugin::registry->lookup<NodeFactory>(type);
if (!nf)
throw RuntimeError("Unknown node-type: {}", type);
return nf->make();
return nf->make(id, name);
}
int NodeFactory::start(SuperNode *sn)

View file

@ -16,13 +16,13 @@ extern "C" {
using namespace villas;
using namespace villas::node;
vnode * node_new(const char *json_str, const char *sn_uuid_str)
vnode * node_new(const char *id_str, const char *json_str)
{
json_error_t err;
uuid_t sn_uuid;
uuid_parse(sn_uuid_str, sn_uuid);
uuid_t id;
uuid_parse(id_str, id);
auto *json = json_loads(json_str, 0, &err);
return (vnode *) NodeFactory::make(json, sn_uuid);
return (vnode *) NodeFactory::make(json, id);
}
int node_prepare(vnode *n)

View file

@ -12,8 +12,8 @@
using namespace villas;
using namespace villas::node;
NodeCompat::NodeCompat(struct NodeCompatType *vt) :
Node(),
NodeCompat::NodeCompat(struct NodeCompatType *vt, const uuid_t &id, const std::string &name) :
Node(id, name),
_vt(vt)
{
_vd = new char[_vt->size];
@ -89,9 +89,9 @@ int NodeCompat::prepare()
return Node::prepare();
}
int NodeCompat::parse(json_t *json, const uuid_t sn_uuid)
int NodeCompat::parse(json_t *json)
{
int ret = Node::parse(json, sn_uuid);
int ret = Node::parse(json);
if (ret)
return ret;
@ -270,9 +270,9 @@ const std::string & NodeCompat::getDetails()
return _details;
}
Node * NodeCompatFactory::make()
Node * NodeCompatFactory::make(const uuid_t &id, const std::string &name)
{
auto *n = new NodeCompat(_vt);
auto *n = new NodeCompat(_vt, id, name);
init(n);

View file

@ -16,8 +16,8 @@ using namespace villas;
using namespace villas::node;
using namespace villas::node::api::universal;
APINode::APINode(const std::string &name) :
Node(name),
APINode::APINode(const uuid_t &id, const std::string &name) :
Node(id, name),
read(),
write()
{
@ -94,9 +94,9 @@ int APINode::_write(struct Sample *smps[], unsigned cnt)
return 1;
}
int APINode::parse(json_t *json, const uuid_t sn_uuid)
int APINode::parse(json_t *json)
{
int ret = Node::parse(json, sn_uuid);
int ret = Node::parse(json);
if (ret)
return ret;

View file

@ -20,8 +20,8 @@ using namespace villas;
using namespace villas::node;
using namespace villas::utils;
ExampleNode::ExampleNode(const std::string &name) :
Node(name),
ExampleNode::ExampleNode(const uuid_t &id, const std::string &name) :
Node(id, name),
setting1(72),
setting2("something"),
state1(0)
@ -40,7 +40,7 @@ int ExampleNode::prepare()
return 0;
}
int ExampleNode::parse(json_t *json, const uuid_t sn_uuid)
int ExampleNode::parse(json_t *json)
{
/* TODO: Add implementation here. The following is just an example */

View file

@ -27,9 +27,9 @@ ExecNode::~ExecNode()
fclose(stream_out);
}
int ExecNode::parse(json_t *json, const uuid_t sn_uuid)
int ExecNode::parse(json_t *json)
{
int ret = Node::parse(json, sn_uuid);
int ret = Node::parse(json);
if (ret)
return ret;

View file

@ -52,7 +52,7 @@ FpgaNode::FpgaNode(const std::string &name) :
FpgaNode::~FpgaNode()
{ }
int FpgaNode::parse(json_t *json, const uuid_t sn_uuid)
int FpgaNode::parse(json_t *json)
{
int ret = Node::parse(json);
if (ret)

View file

@ -630,8 +630,8 @@ int SlaveNode::_write(Sample *samples[], unsigned sample_count)
return sample_count;
}
SlaveNode::SlaveNode(const std::string &name) :
Node(name)
SlaveNode::SlaveNode(const uuid_t &id, const std::string &name) :
Node(id, name)
{
server.state = SlaveNode::Server::NONE;
@ -662,9 +662,9 @@ SlaveNode::~SlaveNode()
destroySlave();
}
int SlaveNode::parse(json_t *json, const uuid_t sn_uuid)
int SlaveNode::parse(json_t *json)
{
int ret = Node::parse(json, sn_uuid);
int ret = Node::parse(json);
if (ret)
return ret;

View file

@ -572,8 +572,8 @@ int GooseNode::_write(Sample *samples[], unsigned sample_count)
return sample_count;
}
GooseNode::GooseNode(const std::string &name) :
Node(name)
GooseNode::GooseNode(const uuid_t &id, const std::string &name) :
Node(id, name)
{
input.state = Input::NONE;
@ -601,12 +601,12 @@ GooseNode::~GooseNode()
err = pool_destroy(&input.pool);
}
int GooseNode::parse(json_t *json, const uuid_t sn_uuid)
int GooseNode::parse(json_t *json)
{
int ret;
json_error_t err;
ret = Node::parse(json, sn_uuid);
ret = Node::parse(json);
if (ret)
return ret;

View file

@ -18,8 +18,8 @@ using namespace villas;
using namespace villas::node;
using namespace villas::utils;
LoopbackNode::LoopbackNode(const std::string &name) :
Node(name),
LoopbackNode::LoopbackNode(const uuid_t &id, const std::string &name) :
Node(id, name),
queuelen(DEFAULT_QUEUE_LENGTH),
mode(QueueSignalledMode::AUTO)
{

View file

@ -20,14 +20,18 @@ using namespace villas::node;
static InternalLoopbackNodeFactory nf;
InternalLoopbackNode::InternalLoopbackNode(Node *src, unsigned id, unsigned ql) :
Node(fmt::format("{}.lo{}", src->getNameShort(), id)),
queuelen(ql),
source(src)
{
auto name = fmt::format("{}.lo{}", src->getNameShort(), id);
uuid_t uuid;
int ret = uuid::generateFromString(uuid, fmt::format("lo{}", id), src->getUuid());
if (ret)
throw RuntimeError("Failed to initialize UUID");
Node(uuid, name);
factory = &nf;
name_long = fmt::format(CLR_RED("{}") "(" CLR_YEL("{}") ")", name_short, nf.getName());

View file

@ -188,8 +188,8 @@ Signal::Ptr SignalNodeSignal::toSignal(Signal::Ptr tpl) const
return sig;
}
SignalNode::SignalNode(const std::string &name) :
Node(name),
SignalNode::SignalNode(const uuid_t &id, const std::string &name) :
Node(id, name),
task(CLOCK_MONOTONIC),
rt(1),
rate(10),
@ -215,9 +215,9 @@ int SignalNode::prepare()
return Node::prepare();
}
int SignalNode::parse(json_t *json, const uuid_t sn_uuid)
int SignalNode::parse(json_t *json)
{
int r = -1, m = -1, ret = Node::parse(json, sn_uuid);
int r = -1, m = -1, ret = Node::parse(json);
if (ret)
return ret;

View file

@ -23,8 +23,8 @@ using namespace villas::utils;
static villas::node::Web *web;
WebRTCNode::WebRTCNode(const std::string &name) :
Node(name),
WebRTCNode::WebRTCNode(const uuid_t &id, const std::string &name) :
Node(id, name),
server("https://villas.k8s.eonerc.rwth-aachen.de/ws/signaling"),
wait_seconds(0),
format(nullptr),
@ -42,9 +42,9 @@ WebRTCNode::~WebRTCNode()
;
}
int WebRTCNode::parse(json_t *json, const uuid_t sn_uuid)
int WebRTCNode::parse(json_t *json)
{
int ret = Node::parse(json, sn_uuid);
int ret = Node::parse(json);
if (ret)
return ret;

View file

@ -128,34 +128,44 @@ void SuperNode::parse(json_t *root)
if (!json_is_object(json_nodes))
throw ConfigError(json_nodes, "node-config-nodes", "Setting 'nodes' must be a group with node name => group mappings.");
const char *name;
const char *node_name;
json_t *json_node;
json_object_foreach(json_nodes, name, json_node) {
const char *type;
json_object_foreach(json_nodes, node_name, json_node) {
uuid_t node_uuid;
const char *node_type;
const char *node_uuid_str = nullptr;
ret = Node::isValidName(name);
ret = Node::isValidName(node_name);
if (!ret)
throw RuntimeError("Invalid name for node: {}", name);
throw RuntimeError("Invalid name for node: {}", node_name);
ret = json_unpack_ex(json_node, &err, 0, "{ s: s }", "type", &type);
ret = json_unpack_ex(json_node, &err, 0, "{ s: s, s?: s }",
"type", &node_type,
"uuid", &node_uuid_str
);
if (ret)
throw ConfigError(root, err, "node-config-node-type", "Failed to parse type of node '{}'", name);
throw ConfigError(root, err, "node-config-node-type", "Failed to parse type of node '{}'", node_name);
json_object_set_new(json_node, "name", json_string(name));
if (node_uuid_str) {
ret = uuid_parse(uuid_str, uuid);
if (ret)
throw ConfigError(json_node, "node-config-node-uuid", "Failed to parse UUID: {}", uuid_str);
}
else
// Generate UUID from node name and super-node UUID
uuid::generateFromString(node_uuid, node_name, uuid);
auto *n = NodeFactory::make(type);
auto *n = NodeFactory::make(node_type, node_uuid, node_name);
if (!n)
throw MemoryAllocationError();
ret = n->parse(json_node, uuid);
ret = n->parse(json_node);
if (ret) {
auto config_id = fmt::format("node-config-node-{}", type);
auto config_id = fmt::format("node-config-node-{}", node_type);
throw ConfigError(json_node, config_id, "Failed to parse configuration of node '{}'", name);
throw ConfigError(json_node, config_id, "Failed to parse configuration of node '{}'", node_name);
}
json_object_del(json_node, "name");
nodes.push_back(n);
}
}