From 90089f97f3b14a0d96790d1501152182fba0035d Mon Sep 17 00:00:00 2001 From: Manik Magar Date: Sun, 6 Nov 2022 10:58:26 -0500 Subject: [PATCH] fix: node connectors with different paths #302 --- .../mulefd/model/KnownMuleComponent.java | 9 ++++ .../mulefd/drawings/GraphDiagramTest.java | 35 +++++++++++++++ .../drawToValidateGraph_APIKIT_Expected.dot | 7 +-- .../mulefd/model/KnownMuleComponentTest.java | 32 ++++++++++++++ src/test/resources/gh-issues/iss-256.dot | 4 +- src/test/resources/gh-issues/iss-302.dot | 43 +++++++++++++++++++ src/test/resources/gh-issues/iss-302.xml | 14 ++++++ .../kafka-flows-mulefd-components-example.dot | 12 +++--- 8 files changed, 145 insertions(+), 11 deletions(-) create mode 100644 src/test/java/com/javastreets/mulefd/model/KnownMuleComponentTest.java create mode 100644 src/test/resources/gh-issues/iss-302.dot create mode 100644 src/test/resources/gh-issues/iss-302.xml diff --git a/src/main/java/com/javastreets/mulefd/model/KnownMuleComponent.java b/src/main/java/com/javastreets/mulefd/model/KnownMuleComponent.java index 8ee5c01..b23caa8 100644 --- a/src/main/java/com/javastreets/mulefd/model/KnownMuleComponent.java +++ b/src/main/java/com/javastreets/mulefd/model/KnownMuleComponent.java @@ -8,4 +8,13 @@ public class KnownMuleComponent extends MuleComponent { public KnownMuleComponent(String type, String name) { super(type, name); } + + @Override + public String qualifiedName() { + String name = super.qualifiedName(); + if (getPath() != null && getPath().getValue() != null) { + name = name + ":" + getPath().getValue(); + } + return name; + } } diff --git a/src/test/java/com/javastreets/mulefd/drawings/GraphDiagramTest.java b/src/test/java/com/javastreets/mulefd/drawings/GraphDiagramTest.java index 225b0bc..49afbc5 100644 --- a/src/test/java/com/javastreets/mulefd/drawings/GraphDiagramTest.java +++ b/src/test/java/com/javastreets/mulefd/drawings/GraphDiagramTest.java @@ -185,6 +185,8 @@ void drawToValidateGraph_APIKIT() throws Exception { ArgumentCaptor graphArgumentCaptor = ArgumentCaptor.forClass(MutableGraph.class); verify(graphDiagram).writGraphToFile(any(File.class), graphArgumentCaptor.capture()); MutableGraph generatedGraph = graphArgumentCaptor.getValue(); + GraphvizEngineHelper.generate(generatedGraph, Format.DOT, + Paths.get("test-output2.dot").toFile()); String generated = GraphvizEngineHelper.generate(generatedGraph, Format.DOT); String ref = new String(Files.readAllBytes(Paths.get( "src/test/java/com/javastreets/mulefd/drawings/drawToValidateGraph_APIKIT_Expected.dot"))); @@ -393,4 +395,37 @@ void writeFlowGraphWithSubFlow() { } + @Test + @DisplayName("Distinguish same connector with different path") + void github_issue_302() throws Exception { + + List flows = + DiagramRendererTestUtil.getFlows(Paths.get("src/test/resources/gh-issues/iss-302.xml")); + File output = new File(".", "output.png"); + DrawingContext context = new DrawingContext(); + context.setDiagramType(DiagramType.GRAPH); + context.setOutputFile(output); + context.setComponents(flows); + + ComponentItem item = new ComponentItem(); + item.setPrefix("vm"); + item.setOperation("publish"); + item.setSource(false); + item.setConfigAttributeName("config-ref"); + item.setPathAttributeName("queueName"); + context.setKnownComponents(Collections.singletonMap(item.qualifiedName(), item)); + + GraphDiagram graphDiagram = Mockito.spy(new GraphDiagram()); + when(graphDiagram.getDiagramHeaderLines()).thenReturn(new String[] {"Test Diagram"}); + graphDiagram.draw(context); + ArgumentCaptor graphArgumentCaptor = ArgumentCaptor.forClass(MutableGraph.class); + verify(graphDiagram).writGraphToFile(any(File.class), graphArgumentCaptor.capture()); + MutableGraph generatedGraph = graphArgumentCaptor.getValue(); + String generated = GraphvizEngineHelper.generate(generatedGraph, Format.DOT); + String ref = + new String(Files.readAllBytes(Paths.get("src/test/resources/gh-issues/iss-302.dot"))); + assertThat(generated).as("DOT Graph").isEqualToNormalizingNewlines(ref); + } + + } diff --git a/src/test/java/com/javastreets/mulefd/drawings/drawToValidateGraph_APIKIT_Expected.dot b/src/test/java/com/javastreets/mulefd/drawings/drawToValidateGraph_APIKIT_Expected.dot index a0d52cf..2e51bc8 100644 --- a/src/test/java/com/javastreets/mulefd/drawings/drawToValidateGraph_APIKIT_Expected.dot +++ b/src/test/java/com/javastreets/mulefd/drawings/drawToValidateGraph_APIKIT_Expected.dot @@ -34,18 +34,18 @@ subgraph "cluster_mule" { edge ["dir"="forward"] graph ["rankdir"="LR","splines"="spline","pad"="1.0,0.5","dpi"="150","label"=>,"labelloc"="t","style"="invis"] edge ["arrowhead"="vee","dir"="forward"] -"http:listener" ["shape"="hexagon","style"="filled","color"="cyan","sourceNode"="true","label"=<http: listener
/api/*
>] +"http:listener:/api/*" ["shape"="hexagon","style"="filled","color"="cyan","sourceNode"="true","label"=<http: listener
/api/*
>] "flow:test-api-main" ["label"=<flow: test-api-main>,"shape"="rectangle","color"="blue"] "apikittest-api-config" ["shape"="doublecircle","color"="cyan","style"="filled","label"=<apikit
test-api-config
>] "flow:put:\users\(userId):test-api-config" ["label"=<flow: put:\users\(userId):test-api-config>,"shape"="rectangle","color"="blue"] "flow:get:\users:test-api-config" ["label"=<flow: get:\users:test-api-config>,"shape"="rectangle","color"="blue"] "flow:get:\users\(userId):test-api-config" ["label"=<flow: get:\users\(userId):test-api-config>,"shape"="rectangle","color"="blue"] "flow:post:\users:test-api-config" ["label"=<flow: post:\users:test-api-config>,"shape"="rectangle","color"="blue"] +"http:listener:/console/*" ["shape"="hexagon","style"="filled","color"="cyan","sourceNode"="true","label"=<http: listener
/console/*
>] "flow:test-api-console" ["label"=<flow: test-api-console>,"shape"="rectangle","color"="blue"] "sub-flow:test-sub-flow" ["label"=<sub-flow: test-sub-flow>,"color"="black","shape"="ellipse"] "sub-flow:test-sub-flow1" ["label"=<sub-flow: test-sub-flow1>,"color"="black","shape"="ellipse"] -"http:listener" -> "flow:test-api-console" ["style"="bold"] -"http:listener" -> "flow:test-api-main" ["style"="bold"] +"http:listener:/api/*" -> "flow:test-api-main" ["style"="bold"] "flow:test-api-main" -> "apikittest-api-config" ["style"="solid","label"="(1)"] "apikittest-api-config" -> "flow:put:\users\(userId):test-api-config" ["style"="solid"] "apikittest-api-config" -> "flow:get:\users:test-api-config" ["style"="solid"] @@ -55,6 +55,7 @@ edge ["arrowhead"="vee","dir"="forward"] "flow:get:\users:test-api-config" -> "sub-flow:test-sub-flow" ["style"="solid","label"="(1)"] "flow:get:\users\(userId):test-api-config" -> "sub-flow:test-sub-flow" ["style"="solid","label"="(1)"] "flow:post:\users:test-api-config" -> "sub-flow:test-sub-flow" ["style"="solid","label"="(1)"] +"http:listener:/console/*" -> "flow:test-api-console" ["style"="bold"] "flow:test-api-console" -> "apikittest-api-config" ["style"="solid","label"="(1)"] "sub-flow:test-sub-flow" -> "sub-flow:test-sub-flow1" ["style"="solid","label"="(1)"] } diff --git a/src/test/java/com/javastreets/mulefd/model/KnownMuleComponentTest.java b/src/test/java/com/javastreets/mulefd/model/KnownMuleComponentTest.java new file mode 100644 index 0000000..b2ef814 --- /dev/null +++ b/src/test/java/com/javastreets/mulefd/model/KnownMuleComponentTest.java @@ -0,0 +1,32 @@ +package com.javastreets.mulefd.model; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class KnownMuleComponentTest { + + @Test + @DisplayName("Qualified name with no path attribute") + void qualifiedName_no_path() { + KnownMuleComponent component = new KnownMuleComponent("prefix", "operation"); + assertThat(component.qualifiedName()).isEqualTo("prefix:operation"); + } + + @Test + @DisplayName("Qualified name with null path value") + void qualifiedName_null_path() { + KnownMuleComponent component = new KnownMuleComponent("prefix", "operation"); + component.setPath(Attribute.with("tag", null)); + assertThat(component.qualifiedName()).isEqualTo("prefix:operation"); + } + + @Test + @DisplayName("Qualified name with path value") + void qualifiedName_some_path() { + KnownMuleComponent component = new KnownMuleComponent("prefix", "operation"); + component.setPath(Attribute.with("tag", "pathValue")); + assertThat(component.qualifiedName()).isEqualTo("prefix:operation:pathValue"); + } +} diff --git a/src/test/resources/gh-issues/iss-256.dot b/src/test/resources/gh-issues/iss-256.dot index d3366c3..7f37827 100644 --- a/src/test/resources/gh-issues/iss-256.dot +++ b/src/test/resources/gh-issues/iss-256.dot @@ -34,13 +34,13 @@ subgraph "cluster_mule" { edge ["dir"="forward"] graph ["rankdir"="LR","splines"="spline","pad"="1.0,0.5","dpi"="150","label"=>,"labelloc"="t","style"="invis"] edge ["arrowhead"="vee","dir"="forward"] -"http:listener" ["shape"="hexagon","style"="filled","color"="cyan","sourceNode"="true","label"=<http: listener
/api/*
>] +"http:listener:/api/*" ["shape"="hexagon","style"="filled","color"="cyan","sourceNode"="true","label"=<http: listener
/api/*
>] "flow:test-api-main" ["label"=<flow: test-api-main>,"shape"="rectangle","color"="blue"] "apikittest-api-config" ["shape"="doublecircle","color"="cyan","style"="filled","label"=<apikit
test-api-config
>] "flow:put:\users\(userId):test-api-config" ["label"=<flow: put:\users\(userId):test-api-config>,"shape"="rectangle","color"="blue"] "flow:get:\users:test-api-config" ["label"=<flow: get:\users:test-api-config>,"shape"="rectangle","color"="blue"] "sub-flow:test-sub-flow" ["label"=<sub-flow: test-sub-flow>,"color"="black","shape"="ellipse"] -"http:listener" -> "flow:test-api-main" ["style"="bold"] +"http:listener:/api/*" -> "flow:test-api-main" ["style"="bold"] "flow:test-api-main" -> "apikittest-api-config" ["style"="solid","label"="(1)"] "apikittest-api-config" -> "flow:put:\users\(userId):test-api-config" ["style"="solid"] "apikittest-api-config" -> "flow:get:\users:test-api-config" ["style"="solid"] diff --git a/src/test/resources/gh-issues/iss-302.dot b/src/test/resources/gh-issues/iss-302.dot new file mode 100644 index 0000000..9761ff1 --- /dev/null +++ b/src/test/resources/gh-issues/iss-302.dot @@ -0,0 +1,43 @@ +digraph "mule" { +edge ["dir"="forward"] +graph ["rankdir"="LR","splines"="spline","pad"="1.0,0.5","dpi"="150","label"=>,"labelloc"="t"] +edge ["arrowhead"="vee","dir"="forward"] +subgraph "cluster_legend" { +edge ["dir"="forward"] +graph ["label"=<Legend>,"style"="dashed"] +"flow" ["fixedsize"="true","width"="1.0","height"="0.25","shape"="rectangle","color"="blue"] +"sub-flow" ["fixedsize"="true","width"="1.0","height"="0.25","color"="black","shape"="ellipse"] +"connector:operation" ["shape"="component"] +"Unused sub/-flow" ["fixedsize"="true","width"="2.0","height"="0.25","color"="gray","style"="filled"] +"Flow A" ["fixedsize"="true","width"="1.0","height"="0.25"] +"sub-flow-1" ["fixedsize"="true","width"="1.25","height"="0.25"] +"Flow C" ["fixedsize"="true","width"="1.0","height"="0.25"] +"sub-flow-C1" ["fixedsize"="true","width"="1.25","height"="0.25"] +"flow source" ["fixedsize"="true","width"="1.5","height"="0.25","shape"="hexagon","style"="filled","color"="cyan","sourceNode"="true"] +"flow self-call" ["fixedsize"="true","width"="1.25","height"="0.25","shape"="rectangle","color"="blue"] +"sub-flow self-call" ["fixedsize"="true","width"="2.0","height"="0.25","color"="black","shape"="ellipse"] +"flow" -> "sub-flow" ["style"="invis"] +"sub-flow" -> "Unused sub/-flow" ["style"="invis"] +"Flow A" -> "sub-flow-1" ["style"="solid","label"="(1)","taillabel"="Call Sequence\n","labelangle"="-5.0","labeldistance"="8.0"] +"Flow C" -> "sub-flow-C1" ["style"="dashed,bold","xlabel"="(1) Async","color"="lightblue3","taillabel"="Asynchronous call\n","labelangle"="-5.0","labeldistance"="8.0"] +"flow source" -> "flow self-call" ["style"="invis"] +"flow self-call" -> "flow self-call" +"flow self-call" -> "sub-flow self-call" ["style"="invis"] +"sub-flow self-call" -> "sub-flow self-call" +} +subgraph "cluster_legend-space" { +edge ["dir"="none"] +graph ["label"="","style"="invis"] +"" ["shape"="none","width"="2.0","height"="1.0"] +} +subgraph "cluster_mule" { +edge ["dir"="forward"] +graph ["rankdir"="LR","splines"="spline","pad"="1.0,0.5","dpi"="150","label"=>,"labelloc"="t","style"="invis"] +edge ["arrowhead"="vee","dir"="forward"] +"flow:mulefdFlow" ["label"=<flow: mulefdFlow>,"shape"="rectangle","color"="blue"] +"vm:publish:queue1" ["shape"="component","label"=<vm: publish
queue1>] +"vm:publish:queue2" ["shape"="component","label"=<vm: publish
queue2>] +"flow:mulefdFlow" -> "vm:publish:queue1" ["style"="solid","label"="(1)"] +"flow:mulefdFlow" -> "vm:publish:queue2" ["style"="solid","label"="(2)"] +} +} \ No newline at end of file diff --git a/src/test/resources/gh-issues/iss-302.xml b/src/test/resources/gh-issues/iss-302.xml new file mode 100644 index 0000000..b2dc64b --- /dev/null +++ b/src/test/resources/gh-issues/iss-302.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + diff --git a/src/test/resources/kafka-flows-mulefd-components-example.dot b/src/test/resources/kafka-flows-mulefd-components-example.dot index 773b435..a2b6571 100644 --- a/src/test/resources/kafka-flows-mulefd-components-example.dot +++ b/src/test/resources/kafka-flows-mulefd-components-example.dot @@ -34,13 +34,13 @@ subgraph "cluster_mule" { edge ["dir"="forward"] graph ["rankdir"="LR","splines"="spline","pad"="1.0,0.5","dpi"="150","label"=>,"labelloc"="t","style"="invis"] edge ["arrowhead"="vee","dir"="forward"] -"http:listener" ["shape"="hexagon","style"="filled","color"="cyan","sourceNode"="true","label"=<http: listener
/pushMessage
>] +"http:listener:/pushMessage" ["shape"="hexagon","style"="filled","color"="cyan","sourceNode"="true","label"=<http: listener
/pushMessage
>] "flow:Producer-Flow" ["label"=<flow: Producer-Flow>,"shape"="rectangle","color"="blue"] -"kafka:publish" ["shape"="component","label"=<kafka: publish
#[payload.topic]>] -"kafka:message-listener" ["shape"="hexagon","style"="filled","color"="cyan","sourceNode"="true","label"=<kafka: message-listener

>] +"kafka:publish:#[payload.topic]" ["shape"="component","label"=<kafka: publish
#[payload.topic]>] +"kafka:message-listener:" ["shape"="hexagon","style"="filled","color"="cyan","sourceNode"="true","label"=<kafka: message-listener

>] "flow:Consumer-Flow" ["label"=<flow: Consumer-Flow>,"shape"="rectangle","color"="blue"] -"http:listener" -> "flow:Producer-Flow" ["style"="bold"] -"flow:Producer-Flow" -> "kafka:publish" ["style"="dashed,bold","xlabel"="(1) Async","color"="lightblue3"] -"kafka:message-listener" -> "flow:Consumer-Flow" ["style"="bold"] +"http:listener:/pushMessage" -> "flow:Producer-Flow" ["style"="bold"] +"flow:Producer-Flow" -> "kafka:publish:#[payload.topic]" ["style"="dashed,bold","xlabel"="(1) Async","color"="lightblue3"] +"kafka:message-listener:" -> "flow:Consumer-Flow" ["style"="bold"] } } \ No newline at end of file