[Logstash] [PipelineViewer] Preserve all nested pipeline statements during graph conversion (#19101)
* Ensure all true/false statements are nested in IfStatements. * Simplify nested vertex diffing. * Rename get vertices function and test it. * Update tests, add more tests. * Update prompted by review feedback. * Update tests - add required props to provided objects. * Remove unneeded function/tests. * PR Cleanup.
This commit is contained in:
parent
72f0f5918b
commit
8425016e66
|
@ -40,18 +40,34 @@ export class IfVertex extends Vertex {
|
|||
return this.outgoingEdges.find(e => e.when === true);
|
||||
}
|
||||
|
||||
get trueEdges() {
|
||||
return this.outgoingEdges.filter(e => e.when === true);
|
||||
}
|
||||
|
||||
get falseEdge() {
|
||||
return this.outgoingEdges.find(e => e.when === false);
|
||||
}
|
||||
|
||||
get falseEdges() {
|
||||
return this.outgoingEdges.filter(e => e.when === false);
|
||||
}
|
||||
|
||||
get trueOutgoingVertex() {
|
||||
return this.trueEdge ? this.trueEdge.to : null;
|
||||
}
|
||||
|
||||
get trueOutgoingVertices() {
|
||||
return this.trueEdges.map(e => e.to);
|
||||
}
|
||||
|
||||
get falseOutgoingVertex() {
|
||||
return this.falseEdge ? this.falseEdge.to : null;
|
||||
}
|
||||
|
||||
get falseOutgoingVertices() {
|
||||
return this.falseEdges.map(e => e.to);
|
||||
}
|
||||
|
||||
get next() {
|
||||
const trueDescendants = this.trueOutgoingVertex ? this.trueOutgoingVertex.descendants().vertices : [];
|
||||
const falseDescendants = this.falseOutgoingVertex ? this.falseOutgoingVertex.descendants().vertices : [];
|
||||
|
|
|
@ -49,6 +49,8 @@ describe('IfStatement class', () => {
|
|||
esVertex.pipelineStage = 'output';
|
||||
|
||||
ifVertex.trueOutgoingVertex = esVertex;
|
||||
ifVertex.trueOutgoingVertices = [ esVertex ];
|
||||
ifVertex.falseOutgoingVertices = [];
|
||||
});
|
||||
|
||||
it('creates a IfStatement from vertex props', () => {
|
||||
|
@ -88,6 +90,9 @@ describe('IfStatement class', () => {
|
|||
|
||||
ifVertex.trueOutgoingVertex = esVertex;
|
||||
ifVertex.falseOutgoingVertex = terminalVertex;
|
||||
|
||||
ifVertex.trueOutgoingVertices = [ esVertex ];
|
||||
ifVertex.falseOutgoingVertices = [ terminalVertex ];
|
||||
});
|
||||
|
||||
it('creates a IfStatement from vertex props', () => {
|
||||
|
@ -126,6 +131,8 @@ describe('IfStatement class', () => {
|
|||
esVertex.pipelineStage = 'output';
|
||||
|
||||
ifVertex.trueOutgoingVertex = esVertex;
|
||||
ifVertex.trueOutgoingVertices = [ esVertex ];
|
||||
ifVertex.falseOutgoingVertices = [];
|
||||
});
|
||||
|
||||
it('creates a IfStatement from vertex props', () => {
|
||||
|
@ -171,6 +178,9 @@ describe('IfStatement class', () => {
|
|||
|
||||
ifVertex.trueOutgoingVertex = esVertex;
|
||||
ifVertex.falseOutgoingVertex = terminalVertex;
|
||||
|
||||
ifVertex.trueOutgoingVertices = [ esVertex ];
|
||||
ifVertex.falseOutgoingVertices = [ terminalVertex ];
|
||||
});
|
||||
|
||||
it('creates a IfStatement from vertex props', () => {
|
||||
|
|
|
@ -1579,6 +1579,185 @@ describe('Pipeline class', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('Pipeline with if having two nested output statements', () => {
|
||||
beforeEach(() => {
|
||||
graph = new Graph();
|
||||
graph.update({
|
||||
vertices: [
|
||||
{
|
||||
id: "the_if",
|
||||
explicit_id: false,
|
||||
type: "if",
|
||||
condition: "[is_rt] == \"RT\"",
|
||||
stats: {}
|
||||
},
|
||||
{
|
||||
plugin_type: "output",
|
||||
type: "plugin",
|
||||
config_name: "stdout",
|
||||
id: "plugin_1",
|
||||
meta: {
|
||||
source: {
|
||||
line: 124,
|
||||
protocol: "str",
|
||||
id: "pipeline",
|
||||
column: 5
|
||||
}
|
||||
},
|
||||
explicit_id: false,
|
||||
stats: null
|
||||
},
|
||||
{
|
||||
plugin_type: "output",
|
||||
type: "plugin",
|
||||
config_name: "elasticsearch",
|
||||
id: "plugin_2",
|
||||
meta: {
|
||||
source: {
|
||||
line: 117,
|
||||
protocol: "str",
|
||||
id: "pipeline",
|
||||
column: 5
|
||||
}
|
||||
},
|
||||
explicit_id: true,
|
||||
stats: null
|
||||
},
|
||||
],
|
||||
edges: [
|
||||
{
|
||||
id: "35591f523dee3465d4c38f20232c56db453a9e4258af5885bf8c79f517690bc5",
|
||||
from: "the_if",
|
||||
to: "plugin_1",
|
||||
type: "boolean",
|
||||
when: true
|
||||
},
|
||||
{
|
||||
id: "591f523dee3465d4c38f20232c56db453a9e4258af5885bf8c79f517690bc535",
|
||||
from: "the_if",
|
||||
to: "plugin_2",
|
||||
type: "boolean",
|
||||
when: true
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
it('has two child statements', () => {
|
||||
const pipeline = Pipeline.fromPipelineGraph(graph);
|
||||
|
||||
expect(pipeline.outputStatements.length).to.be(1);
|
||||
const { trueStatements } = pipeline.outputStatements[0];
|
||||
expect(trueStatements.length).to.be(2);
|
||||
expect(trueStatements[0].id).to.be('plugin_1');
|
||||
expect(trueStatements[1].id).to.be('plugin_2');
|
||||
expect(pipeline.outputStatements[0].elseStatements.length).to.be(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Pipeline with if having two nested else statements', () => {
|
||||
beforeEach(() => {
|
||||
graph = new Graph();
|
||||
graph.update({
|
||||
vertices: [
|
||||
{
|
||||
id: "the_if",
|
||||
explicit_id: false,
|
||||
type: "if",
|
||||
condition: "[is_rt] == \"RT\"",
|
||||
stats: {}
|
||||
},
|
||||
{
|
||||
plugin_type: "output",
|
||||
type: "plugin",
|
||||
config_name: "stdout",
|
||||
id: "plugin_1",
|
||||
meta: {
|
||||
source: {
|
||||
line: 124,
|
||||
protocol: "str",
|
||||
id: "pipeline",
|
||||
column: 5
|
||||
}
|
||||
},
|
||||
explicit_id: false,
|
||||
stats: null
|
||||
},
|
||||
{
|
||||
plugin_type: "output",
|
||||
type: "plugin",
|
||||
config_name: "elasticsearch",
|
||||
id: "plugin_2",
|
||||
meta: {
|
||||
source: {
|
||||
line: 117,
|
||||
protocol: "str",
|
||||
id: "pipeline",
|
||||
column: 5
|
||||
}
|
||||
},
|
||||
explicit_id: true,
|
||||
stats: null
|
||||
},
|
||||
{
|
||||
plugin_type: "output",
|
||||
type: "plugin",
|
||||
config_name: "stdout",
|
||||
id: "plugin_3",
|
||||
meta: {
|
||||
source: {
|
||||
line: 120,
|
||||
protocol: "str",
|
||||
id: "pipeline",
|
||||
column: 5
|
||||
}
|
||||
},
|
||||
explicit_id: false,
|
||||
stats: null
|
||||
},
|
||||
],
|
||||
edges: [
|
||||
{
|
||||
id: "35591f523dee3465d4c38f20232c56db453a9e4258af5885bf8c79f517690bc5",
|
||||
from: "the_if",
|
||||
to: "plugin_1",
|
||||
type: "boolean",
|
||||
when: false
|
||||
},
|
||||
{
|
||||
id: "591f523dee3465d4c38f20232c56db453a9e4258af5885bf8c79f517690bc535",
|
||||
from: "the_if",
|
||||
to: "plugin_2",
|
||||
type: "boolean",
|
||||
when: false
|
||||
},
|
||||
{
|
||||
id: "637281923dee3465d4c38f20232c56db453a9e4258af5885bf8c79f517690bc5",
|
||||
from: "the_if",
|
||||
to: "plugin_3",
|
||||
type: "boolean",
|
||||
when: true
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
it('has two child else statements', () => {
|
||||
const pipeline = Pipeline.fromPipelineGraph(graph);
|
||||
|
||||
expect(pipeline.outputStatements.length).to.be(1);
|
||||
const {
|
||||
trueStatements,
|
||||
elseStatements
|
||||
} = pipeline.outputStatements[0];
|
||||
expect(trueStatements.length).to.be(1);
|
||||
expect(trueStatements[0].id).to.be('plugin_3');
|
||||
expect(elseStatements.length).to.be(2);
|
||||
expect(elseStatements[0].id).to.be('plugin_1');
|
||||
expect(elseStatements[1].id).to.be('plugin_2');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Pipeline with nested ifs', () => {
|
||||
beforeEach(() => {
|
||||
graph = new Graph();
|
||||
|
|
|
@ -8,6 +8,16 @@ import { Statement } from './statement';
|
|||
import { makeStatement } from './make_statement';
|
||||
import { isVertexPipelineStage } from './utils';
|
||||
|
||||
function makeStatementsForOutgoingVertices(outgoingVertices, statements, next, pipelineStage) {
|
||||
outgoingVertices.forEach(vertex => {
|
||||
let currentVertex = vertex;
|
||||
while(isVertexPipelineStage(currentVertex, pipelineStage) && (currentVertex !== next)) {
|
||||
statements.push(makeStatement(currentVertex, pipelineStage));
|
||||
currentVertex = currentVertex.next;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export class IfStatement extends Statement {
|
||||
constructor(vertex, trueStatements, elseStatements) {
|
||||
super(vertex);
|
||||
|
@ -22,22 +32,15 @@ export class IfStatement extends Statement {
|
|||
static fromPipelineGraphVertex(ifVertex, pipelineStage) {
|
||||
const trueStatements = [];
|
||||
const elseStatements = [];
|
||||
const {
|
||||
trueOutgoingVertices,
|
||||
falseOutgoingVertices
|
||||
} = ifVertex;
|
||||
|
||||
const trueVertex = ifVertex.trueOutgoingVertex;
|
||||
const falseVertex = ifVertex.falseOutgoingVertex;
|
||||
const next = ifVertex.next;
|
||||
|
||||
let currentVertex = trueVertex;
|
||||
while (isVertexPipelineStage(currentVertex, pipelineStage) && (currentVertex !== next)) {
|
||||
trueStatements.push(makeStatement(currentVertex, pipelineStage));
|
||||
currentVertex = currentVertex.next;
|
||||
}
|
||||
|
||||
currentVertex = falseVertex;
|
||||
while (currentVertex && isVertexPipelineStage(currentVertex, pipelineStage) && (currentVertex !== next)) {
|
||||
elseStatements.push(makeStatement(currentVertex, pipelineStage));
|
||||
currentVertex = currentVertex.next;
|
||||
}
|
||||
makeStatementsForOutgoingVertices(trueOutgoingVertices, trueStatements, next, pipelineStage);
|
||||
makeStatementsForOutgoingVertices(falseOutgoingVertices, elseStatements, next, pipelineStage);
|
||||
|
||||
return new IfStatement(
|
||||
ifVertex,
|
||||
|
|
Loading…
Reference in a new issue