Hello dear colleges
We have a Nodered server and we want to define some reports from the existing flows.json file regarding paths in the flows :
- begininng with one of the specific node types (kafka-consumer", "kafkajs-consumer", "kafka-producer","kafkajs-producer", "mqtt in", "mqtt out", "http request")
- ending with again one of the specific node types (kafka-consumer", "kafkajs-consumer", "kafka-producer","kafkajs-producer", "mqtt in", "mqtt out", "http request")
We want to list the found paths just with starting node and its properties and ending node with its properties in text files.(not the whole path with nodes between)
Therefore I have tried following C# code, but the code cannot find any path with this criteria , althought a lot of are existing. I tried to add also a jpg image that is showing one example , but unfortunately I got always errors during uploading.
using Newtonsoft.Json.Linq;
static void Main(string[] args)
{
string jsonFilePath = "C:\\temp\\Nodered\\flows.json";
string activeFlowsFile = "C:\\temp\\Nodered\\activeflows.txt";
string outputDirectory = "C:\\temp\\Nodered";
// Parse the JSON file
var json = File.ReadAllText(jsonFilePath);
var nodes = JArray.Parse(json);
// Filter active flows and write their names to activeflows.txt
var activeFlows = new List<string>();
foreach (var node in nodes)
{
if (node["type"]?.ToString() == "tab" && node["disabled"]?.ToObject<bool>() != true)
{
activeFlows.Add(node["label"]?.ToString());
}
}
Directory.CreateDirectory(outputDirectory);
File.WriteAllLines(activeFlowsFile, activeFlows);
// Process each active flow
foreach (var flowName in activeFlows)
{
ProcessFlow(flowName, nodes, outputDirectory);
}
Console.WriteLine($"Processing complete. Results saved to {outputDirectory}");
}
static void ProcessFlow(string flowName, JArray nodes, string outputDirectory)
{
// Filter nodes belonging to the flow
var flowNodes = new Dictionary<string, JToken>();
foreach (var node in nodes)
{
if (node["z"]?.ToString() == flowName)
{
flowNodes[node["id"]?.ToString()] = node;
}
}
// Define start and end node types
var startNodeTypes = new HashSet<string>
{
"kafka-consumer", "kafkajs-consumer", "kafka-producer",
"kafkajs-producer", "mqtt in", "mqtt out", "http request"
};
var endNodeTypes = new HashSet<string>
{
"kafka-consumer", "kafkajs-consumer", "kafka-producer",
"kafkajs-producer", "mqtt in", "mqtt out", "http request"
};
// Find starting and endpoint matches
var results = new List<string>();
foreach (var node in flowNodes.Values)
{
if (startNodeTypes.Contains(node["type"]?.ToString()))
{
var startNodeId = node["id"]?.ToString();
var endpoints = FindEndpoints(flowNodes, startNodeId, endNodeTypes);
foreach (var endpoint in endpoints)
{
results.Add($"Starting Node: {node}\nMatched Endpoint: {endpoint}\n");
}
}
}
// Write results to flow-specific file
string outputFilePath = Path.Combine(outputDirectory, $"{flowName}.txt");
File.WriteAllLines(outputFilePath, results);
}
static List<JToken> FindEndpoints(Dictionary<string, JToken> flowNodes, string startNodeId, HashSet<string> endNodeTypes)
{
var visited = new HashSet<string>();
var endpoints = new List<JToken>();
void Traverse(string nodeId)
{
if (visited.Contains(nodeId) || !flowNodes.ContainsKey(nodeId))
return;
visited.Add(nodeId);
var node = flowNodes[nodeId];
if (endNodeTypes.Contains(node["type"]?.ToString()))
{
endpoints.Add(node);
return;
}
var wires = node["wires"] as JArray;
if (wires != null)
{
foreach (var wireGroup in wires)
{
foreach (var connectedId in wireGroup)
{
Traverse(connectedId.ToString());
}
}
}
}
Traverse(startNodeId);
return endpoints;
}