Files
DMF-Studio/libs/dmf-engine/src/graph.cpp
T
Johanness 1d6f93679f fix: engine REST API - handle GET/DELETE requests immediately, use user-provided node IDs
- Use lws_http_get_uri_and_method() for proper HTTP method detection
  (GET, POST, PUT, DELETE all supported)
- Handle GET/DELETE in LWS_CALLBACK_HTTP without waiting for body
- Support user-provided node IDs via config.id field
- Fixes all REST API endpoints hanging on GET requests
2026-05-26 21:08:06 +03:00

141 lines
3.9 KiB
C++

#include <dmf-engine/graph.hpp>
#include <nlohmann/json.hpp>
#include <spdlog/spdlog.h>
namespace dmf_engine {
NodeId Graph::add_node(const std::string& type, const nlohmann::json& config) {
std::string id;
if (config.contains("id") && config["id"].is_string()) {
id = config["id"].get<std::string>();
} else {
id = type + "_" + std::to_string(next_node_num_++);
}
GraphNode node;
node.id = id;
node.type = type;
node.config = config;
node.state = NodeState::Stopped;
nodes_[id] = std::move(node);
spdlog::info("Graph: added node '{}' type='{}'", id, type);
return id;
}
bool Graph::remove_node(const NodeId& node_id) {
auto it = nodes_.find(node_id);
if (it == nodes_.end()) {
spdlog::warn("Graph: node '{}' not found", node_id);
return false;
}
std::vector<EdgeId> edges_to_remove;
for (const auto& [eid, edge] : edges_) {
if (edge.from_node == node_id || edge.to_node == node_id) {
edges_to_remove.push_back(eid);
}
}
for (const auto& eid : edges_to_remove) {
edges_.erase(eid);
spdlog::info("Graph: removed edge '{}' (connected to removed node '{}')", eid, node_id);
}
nodes_.erase(it);
spdlog::info("Graph: removed node '{}'", node_id);
return true;
}
const GraphNode* Graph::get_node(const NodeId& node_id) const {
auto it = nodes_.find(node_id);
return it != nodes_.end() ? &it->second : nullptr;
}
std::vector<GraphNode> Graph::get_nodes() const {
std::vector<GraphNode> result;
for (const auto& [_, node] : nodes_) {
result.push_back(node);
}
return result;
}
EdgeId Graph::add_edge(const NodeId& from_node, const PortId& from_port,
const NodeId& to_node, const PortId& to_port,
const FlowId& flow_id, const nlohmann::json& flow_def) {
auto id = from_node + ":" + from_port + "->" + to_node + ":" + to_port;
GraphEdge edge;
edge.id = id;
edge.from_node = from_node;
edge.from_port = from_port;
edge.to_node = to_node;
edge.to_port = to_port;
edge.flow_id = flow_id;
edge.flow_def = flow_def;
edges_[id] = std::move(edge);
spdlog::info("Graph: added edge '{}' flow_id={}", id, flow_id);
return id;
}
bool Graph::remove_edge(const EdgeId& edge_id) {
auto it = edges_.find(edge_id);
if (it == edges_.end()) {
spdlog::warn("Graph: edge '{}' not found", edge_id);
return false;
}
edges_.erase(it);
spdlog::info("Graph: removed edge '{}'", edge_id);
return true;
}
std::vector<GraphEdge> Graph::get_edges() const {
std::vector<GraphEdge> result;
for (const auto& [_, edge] : edges_) {
result.push_back(edge);
}
return result;
}
std::vector<GraphEdge> Graph::get_edges_for_node(const NodeId& node_id) const {
std::vector<GraphEdge> result;
for (const auto& [_, edge] : edges_) {
if (edge.from_node == node_id || edge.to_node == node_id) {
result.push_back(edge);
}
}
return result;
}
nlohmann::json Graph::serialize() const {
auto j = nlohmann::json::object();
auto nodes_arr = nlohmann::json::array();
for (const auto& [id, node] : nodes_) {
nodes_arr.push_back({
{"id", node.id},
{"type", node.type},
{"config", node.config},
{"state", static_cast<int>(node.state)},
{"control_port", node.control_port},
{"pid", node.pid},
});
}
j["nodes"] = nodes_arr;
auto edges_arr = nlohmann::json::array();
for (const auto& [id, edge] : edges_) {
edges_arr.push_back({
{"id", edge.id},
{"from_node", edge.from_node},
{"from_port", edge.from_port},
{"to_node", edge.to_node},
{"to_port", edge.to_port},
{"flow_id", edge.flow_id},
});
}
j["edges"] = edges_arr;
return j;
}
} // namespace dmf_engine