├── camel-plantuml-jar ├── src │ ├── main │ │ ├── resources │ │ │ ├── plantuml │ │ │ │ ├── footerTemplate │ │ │ │ ├── consumerTemplate │ │ │ │ ├── producerTemplate │ │ │ │ ├── routeTemplateNoDescription │ │ │ │ ├── endpointTemplate │ │ │ │ ├── routeTemplate │ │ │ │ ├── dynamicProducerTemplate │ │ │ │ ├── dynamicConsumerTemplate │ │ │ │ └── headerTemplate │ │ │ └── log4j2.properties │ │ └── java │ │ │ └── io │ │ │ └── github │ │ │ └── ncasaux │ │ │ ├── CamelPlantUml.java │ │ │ └── camelplantuml │ │ │ ├── model │ │ │ ├── EndpointBaseUriInfo.java │ │ │ ├── RouteInfo.java │ │ │ ├── ConsumerInfo.java │ │ │ ├── query │ │ │ │ └── Parameters.java │ │ │ └── ProducerInfo.java │ │ │ ├── utils │ │ │ ├── ConsumerUtils.java │ │ │ ├── JmxUtils.java │ │ │ ├── RouteUtils.java │ │ │ ├── ProducerUtils.java │ │ │ └── EndpointUtils.java │ │ │ ├── generator │ │ │ ├── FooterDiagramGenerator.java │ │ │ ├── HeaderDiagramGenerator.java │ │ │ ├── EndpointsDiagramGenerator.java │ │ │ ├── RoutesDiagramGenerator.java │ │ │ ├── ConsumersDiagramGenerator.java │ │ │ └── ProducersDiagramGenerator.java │ │ │ ├── extractor │ │ │ ├── processor │ │ │ │ ├── SendDynamicProcessorInfoExtractor.java │ │ │ │ ├── SendProcessorInfoExtractor.java │ │ │ │ ├── WireTapProcessorInfoExtractor.java │ │ │ │ ├── EnricherInfoExtractor.java │ │ │ │ ├── PollEnricherInfoExtractor.java │ │ │ │ └── RecipientListInfoExtractor.java │ │ │ └── RoutesInfoExtractor.java │ │ │ ├── routebuilder │ │ │ └── CamelPlantUmlRouteBuilder.java │ │ │ └── processor │ │ │ └── GetRoutesInfoProcessor.java │ └── test │ │ └── java │ │ ├── Enricher │ │ ├── EnricherHeaderTest.java │ │ ├── EnricherConstantTest.java │ │ └── EnricherSimpleTest.java │ │ ├── RecipientList │ │ ├── RecipientListHeaderTest.java │ │ ├── RecipientListConstantTest.java │ │ └── RecipientListSimpleTest.java │ │ ├── PollEnricher │ │ ├── PollEnricherHeaderTest.java │ │ ├── PollEnricherConstantTest.java │ │ └── PollEnricherSimpleTest.java │ │ ├── WireTap │ │ ├── WireTapStaticTest.java │ │ └── WireTapDynamicTest.java │ │ └── DefaultExample │ │ ├── DefaultExampleWithConnectRoutesTest.java │ │ ├── DefaultExampleWithUriFilterPatternTest.java │ │ ├── DefaultExampleTest.java │ │ ├── DefaultExampleWithHostAndPortTest.java │ │ ├── DefaultExampleWithStoppedRouteTest.java │ │ ├── DefaultExampleWithDuplicateProducerTest.java │ │ └── DefaultExampleWithInvalidUriFilterPatternTest.java └── pom.xml ├── .gitignore ├── camel-plantuml-zip ├── src │ └── main │ │ └── assembly │ │ └── zip.xml └── pom.xml ├── LICENSE ├── .github └── workflows │ └── maven.yml ├── pom.xml ├── README.md └── images ├── example1.light.svg └── example1.full.svg /camel-plantuml-jar/src/main/resources/plantuml/footerTemplate: -------------------------------------------------------------------------------- 1 | @enduml 2 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/resources/plantuml/consumerTemplate: -------------------------------------------------------------------------------- 1 | %%endpointElementId%% --> %%routeElementId%% : %%processorType%% -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/resources/plantuml/producerTemplate: -------------------------------------------------------------------------------- 1 | %%routeElementId%% --> %%targetElementId%% : %%processorType%% -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/resources/plantuml/routeTemplateNoDescription: -------------------------------------------------------------------------------- 1 | rectangle %%routeElementId%% <> as " 2 | %%routeId%% 3 | " -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/resources/plantuml/endpointTemplate: -------------------------------------------------------------------------------- 1 | queue %%endpointElementId%% <><> as " 2 | %%endpointBaseUri%% 3 | " -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/resources/plantuml/routeTemplate: -------------------------------------------------------------------------------- 1 | rectangle %%routeElementId%% <> as " 2 | %%routeId%% 3 | .... 4 | %%routeDescription%% 5 | " -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/resources/plantuml/dynamicProducerTemplate: -------------------------------------------------------------------------------- 1 | queue %%endpointElementId%% <><> as " 2 | %%uri%% 3 | " 4 | 5 | %%routeElementId%% --> %%endpointElementId%% : %%processorType%% -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/resources/plantuml/dynamicConsumerTemplate: -------------------------------------------------------------------------------- 1 | queue %%endpointElementId%% <><> as " 2 | %%uri%% 3 | " 4 | 5 | %%endpointElementId%% --> %%routeElementId%% : %%processorType%% -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/resources/log4j2.properties: -------------------------------------------------------------------------------- 1 | appender.out.type=Console 2 | appender.out.name=out 3 | appender.out.layout.type=PatternLayout 4 | appender.out.layout.pattern=[%30.30t] %-30.30c{1} %-5p %m%n 5 | rootLogger.level=INFO 6 | rootLogger.appenderRef.out.ref=out 7 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/java/io/github/ncasaux/CamelPlantUml.java: -------------------------------------------------------------------------------- 1 | package io.github.ncasaux; 2 | 3 | import io.github.ncasaux.camelplantuml.routebuilder.CamelPlantUmlRouteBuilder; 4 | import org.apache.camel.main.Main; 5 | 6 | public class CamelPlantUml { 7 | public static void main(String... args) throws Exception { 8 | Main main = new Main(); 9 | main.configure().addRoutesBuilder(new CamelPlantUmlRouteBuilder()); 10 | main.run(args); 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/java/io/github/ncasaux/camelplantuml/model/EndpointBaseUriInfo.java: -------------------------------------------------------------------------------- 1 | package io.github.ncasaux.camelplantuml.model; 2 | 3 | public class EndpointBaseUriInfo { 4 | private String diagramElementId; 5 | 6 | public EndpointBaseUriInfo() { 7 | } 8 | 9 | public void setDiagramElementId(String diagramElementId) { 10 | this.diagramElementId = diagramElementId; 11 | } 12 | 13 | public String getDiagramElementId() { 14 | return diagramElementId; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/java/io/github/ncasaux/camelplantuml/utils/ConsumerUtils.java: -------------------------------------------------------------------------------- 1 | package io.github.ncasaux.camelplantuml.utils; 2 | 3 | import io.github.ncasaux.camelplantuml.model.ConsumerInfo; 4 | import org.slf4j.Logger; 5 | 6 | import java.util.ArrayList; 7 | 8 | public class ConsumerUtils { 9 | 10 | public static void addConsumerInfo(ArrayList al, ConsumerInfo ci, Logger LOGGER) { 11 | al.add(ci); 12 | LOGGER.info("{} added to the list of consumers ", ci.toString()); 13 | } 14 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/java/io/github/ncasaux/camelplantuml/utils/JmxUtils.java: -------------------------------------------------------------------------------- 1 | package io.github.ncasaux.camelplantuml.utils; 2 | 3 | import javax.management.remote.JMXConnector; 4 | import javax.management.remote.JMXConnectorFactory; 5 | import javax.management.remote.JMXServiceURL; 6 | import java.io.IOException; 7 | 8 | public class JmxUtils { 9 | public static JMXConnector getConnector(String jmxHost) throws IOException { 10 | String url = "service:jmx:rmi:///jndi/rmi://" + jmxHost + "/jmxrmi"; 11 | JMXServiceURL serviceURL = new JMXServiceURL(url); 12 | return JMXConnectorFactory.connect(serviceURL); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/java/io/github/ncasaux/camelplantuml/generator/FooterDiagramGenerator.java: -------------------------------------------------------------------------------- 1 | package io.github.ncasaux.camelplantuml.generator; 2 | 3 | import org.apache.commons.io.IOUtils; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import java.io.IOException; 8 | import java.nio.charset.StandardCharsets; 9 | import java.util.Objects; 10 | 11 | public class FooterDiagramGenerator { 12 | 13 | private static final Logger LOGGER = LoggerFactory.getLogger(FooterDiagramGenerator.class); 14 | 15 | public static String generateUmlString() throws IOException { 16 | 17 | return IOUtils.toString(Objects.requireNonNull(FooterDiagramGenerator.class.getClassLoader().getResourceAsStream("plantuml/footerTemplate")), StandardCharsets.UTF_8); 18 | } 19 | } -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/resources/plantuml/headerTemplate: -------------------------------------------------------------------------------- 1 | @startuml 2 | 3 | skinparam ArrowColor #Black 4 | 5 | skinparam rectangle { 6 | RoundCorner 20 7 | } 8 | 9 | skinparam rectangle<> { 10 | BorderColor #6C8EBF 11 | BackgroundColor #DAE8FC 12 | } 13 | 14 | skinparam queue<> { 15 | } 16 | 17 | skinparam queue<> { 18 | BorderColor #B85450 19 | BackgroundColor #F8CECC 20 | } 21 | 22 | skinparam queue<> { 23 | BorderColor #82B366 24 | BackgroundColor #D5E8D4 25 | } 26 | 27 | footer Generated with camel-plantuml on %date("dd-MM-yyyy HH:mm") 28 | 29 | ' === Some useful settings for tweaking diagram layout === 30 | 'left to right direction 31 | 'hide stereotype 32 | 'skinparam nodesep 50 33 | 'skinparam ranksep 50 34 | 'skinparam wrapWidth 250 -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/java/io/github/ncasaux/camelplantuml/utils/RouteUtils.java: -------------------------------------------------------------------------------- 1 | package io.github.ncasaux.camelplantuml.utils; 2 | 3 | import io.github.ncasaux.camelplantuml.model.RouteInfo; 4 | import org.apache.commons.codec.digest.DigestUtils; 5 | import org.slf4j.Logger; 6 | 7 | import java.util.HashMap; 8 | 9 | public class RouteUtils { 10 | 11 | public static void addRouteInfo(HashMap routesInfo, 12 | String routeId, 13 | RouteInfo routeInfo, 14 | Logger LOGGER) { 15 | 16 | routeInfo.setDiagramElementId("route_".concat(DigestUtils.md5Hex(routeId))); 17 | routesInfo.put(routeId, routeInfo); 18 | LOGGER.info("{} and routeId \"{}\" added to the map of routes", routeInfo, routeId); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/java/io/github/ncasaux/camelplantuml/utils/ProducerUtils.java: -------------------------------------------------------------------------------- 1 | package io.github.ncasaux.camelplantuml.utils; 2 | 3 | import io.github.ncasaux.camelplantuml.model.ProducerInfo; 4 | import org.slf4j.Logger; 5 | 6 | import java.util.ArrayList; 7 | 8 | public class ProducerUtils { 9 | 10 | public static void addProducerInfoIfNotInList(ArrayList al, ProducerInfo pi, Logger LOGGER) { 11 | if (!al.contains(pi)) { 12 | al.add(pi); 13 | LOGGER.info("{} added to the list of producers ", pi.toString()); 14 | } else { 15 | LOGGER.info("{} already in the list of producers", pi.toString()); 16 | } 17 | } 18 | 19 | public static void addProducerInfo(ArrayList al, ProducerInfo pi, Logger LOGGER) { 20 | al.add(pi); 21 | LOGGER.info("{} added to the list of producers ", pi.toString()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/java/io/github/ncasaux/camelplantuml/generator/HeaderDiagramGenerator.java: -------------------------------------------------------------------------------- 1 | package io.github.ncasaux.camelplantuml.generator; 2 | 3 | import org.apache.commons.io.IOUtils; 4 | import org.apache.commons.lang3.StringUtils; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | import java.io.IOException; 9 | import java.nio.charset.StandardCharsets; 10 | import java.util.Objects; 11 | 12 | public class HeaderDiagramGenerator { 13 | 14 | private static final Logger LOGGER = LoggerFactory.getLogger(HeaderDiagramGenerator.class); 15 | 16 | public static String generateUmlString(String contextName) throws IOException { 17 | 18 | String umlHeaderTemplate = IOUtils.toString(Objects.requireNonNull(HeaderDiagramGenerator.class.getClassLoader().getResourceAsStream("plantuml/headerTemplate")), StandardCharsets.UTF_8); 19 | 20 | return umlHeaderTemplate.concat("\n\n"); 21 | } 22 | } -------------------------------------------------------------------------------- /camel-plantuml-jar/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | camel-plantuml 7 | io.github.ncasaux 8 | 1.8.0 9 | 10 | 4.0.0 11 | 12 | camel-plantuml-jar 13 | bundle 14 | 15 | 16 | install 17 | 18 | 19 | org.apache.felix 20 | maven-bundle-plugin 21 | true 22 | 5.1.9 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /camel-plantuml-zip/src/main/assembly/zip.xml: -------------------------------------------------------------------------------- 1 | 4 | zip 5 | true 6 | 7 | zip 8 | 9 | 10 | 11 | ${project.build.directory}/${project.artifactId}-${project.version}.jar 12 | / 13 | 14 | 15 | 16 | 17 | lib 18 | 19 | ${project.groupId}:${project.artifactId}:jar:* 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/java/io/github/ncasaux/camelplantuml/model/RouteInfo.java: -------------------------------------------------------------------------------- 1 | package io.github.ncasaux.camelplantuml.model; 2 | 3 | public class RouteInfo { 4 | private final String endpointBaseUri; 5 | private final String description; 6 | private String diagramElementId; 7 | 8 | public RouteInfo(String endpointBaseUri, String description) { 9 | this.description = description; 10 | this.endpointBaseUri = endpointBaseUri; 11 | } 12 | 13 | @Override 14 | public String toString() { 15 | return "Route consuming from endpointBaseUri \"".concat(endpointBaseUri).concat("\""); 16 | } 17 | 18 | public String getEndpointBaseUri() { 19 | return endpointBaseUri; 20 | } 21 | 22 | public String getDescription() { 23 | return description; 24 | } 25 | 26 | public String getDiagramElementId() { 27 | return diagramElementId; 28 | } 29 | 30 | public void setDiagramElementId(String diagramElementId) { 31 | this.diagramElementId = diagramElementId; 32 | } 33 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Nicolas CASAUX 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/java/io/github/ncasaux/camelplantuml/model/ConsumerInfo.java: -------------------------------------------------------------------------------- 1 | package io.github.ncasaux.camelplantuml.model; 2 | 3 | public class ConsumerInfo { 4 | private final String routeId; 5 | private final String endpointUri; 6 | private final String processorType; 7 | private final Boolean useDynamicEndpoint; 8 | 9 | public ConsumerInfo(String routeId, String endpointUri, String processorType, Boolean useDynamicEndpoint) { 10 | this.routeId = routeId; 11 | this.endpointUri = endpointUri; 12 | this.processorType = processorType; 13 | this.useDynamicEndpoint = useDynamicEndpoint; 14 | } 15 | 16 | @Override 17 | public String toString() { 18 | return "Consumer in routeId \"".concat(routeId).concat("\" ") 19 | .concat("consuming from ").concat(useDynamicEndpoint ? "dynamic " : "static ") 20 | .concat("URI \"").concat(endpointUri).concat("\" ") 21 | .concat("through processor \"").concat(processorType).concat("\""); 22 | } 23 | 24 | public Boolean getUseDynamicEndpoint() { 25 | return useDynamicEndpoint; 26 | } 27 | 28 | public String getProcessorType() { 29 | return processorType; 30 | } 31 | 32 | public String getRouteId() { 33 | return routeId; 34 | } 35 | 36 | public String getEndpointUri() { 37 | return endpointUri; 38 | } 39 | } -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Maven 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven 3 | 4 | name: Java CI with Maven 5 | 6 | on: 7 | push: 8 | branches: [ main ] 9 | pull_request: 10 | branches: [ main ] 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v4.2.2 17 | - name: Set up Java JDK 18 | uses: actions/setup-java@v4.5.0 19 | with: 20 | java-version: 17 21 | distribution: adopt 22 | - name: Build with Maven 23 | run: mvn -B package --file pom.xml 24 | - name: Cache Maven packages 25 | uses: actions/cache@v4.1.2 26 | with: 27 | path: ~/.m2 28 | key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} 29 | restore-keys: ${{ runner.os }}-m2 30 | - name: Set up Maven Central Repository 31 | uses: actions/setup-java@v4.5.0 32 | with: 33 | java-version: 17 34 | distribution: adopt 35 | server-id: ossrh 36 | server-username: MAVEN_USERNAME 37 | server-password: MAVEN_PASSWORD 38 | gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} 39 | gpg-passphrase: MAVEN_GPG_PASSPHRASE 40 | - name: Deploy with Maven 41 | run: mvn -B clean deploy -Pci-cd 42 | env: 43 | MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} 44 | MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} 45 | MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }} 46 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/java/io/github/ncasaux/camelplantuml/model/query/Parameters.java: -------------------------------------------------------------------------------- 1 | package io.github.ncasaux.camelplantuml.model.query; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | import java.net.URLDecoder; 7 | import java.nio.charset.StandardCharsets; 8 | import java.util.Objects; 9 | import java.util.regex.Pattern; 10 | import java.util.regex.PatternSyntaxException; 11 | 12 | public class Parameters { 13 | private static final Logger LOGGER = LoggerFactory.getLogger(Parameters.class); 14 | private static final String MATCH_NOTHING_PATTERN_STRING = "(?!.*)"; 15 | 16 | private final boolean connectRoutes; 17 | 18 | private final Pattern uriFilterPattern; 19 | 20 | public Parameters(boolean connectRoutes, 21 | String uriFilterPatternString) { 22 | this.connectRoutes = connectRoutes; 23 | 24 | Pattern validUriFilterPattern; 25 | try { 26 | validUriFilterPattern = Pattern.compile(URLDecoder.decode(Objects.requireNonNullElse(uriFilterPatternString, MATCH_NOTHING_PATTERN_STRING), 27 | StandardCharsets.UTF_8)); 28 | LOGGER.info("Value for uriFilterPattern \"{}\"", uriFilterPatternString); 29 | } catch (PatternSyntaxException e) { 30 | LOGGER.info("Invalid value for uriFilterPattern \"{}\"; will be deactivated", uriFilterPatternString); 31 | validUriFilterPattern = Pattern.compile(MATCH_NOTHING_PATTERN_STRING); 32 | } 33 | 34 | this.uriFilterPattern = validUriFilterPattern; 35 | } 36 | 37 | public boolean connectRoutes() { 38 | return connectRoutes; 39 | } 40 | 41 | public Pattern uriFilterPattern() { 42 | return uriFilterPattern; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/java/io/github/ncasaux/camelplantuml/model/ProducerInfo.java: -------------------------------------------------------------------------------- 1 | package io.github.ncasaux.camelplantuml.model; 2 | 3 | public class ProducerInfo { 4 | private final String routeId; 5 | private final String endpointUri; 6 | private final String processorType; 7 | private final Boolean useDynamicEndpoint; 8 | 9 | public ProducerInfo(String routeId, String endpointUri, String processorType, Boolean useDynamicEndpoint) { 10 | this.routeId = routeId; 11 | this.endpointUri = endpointUri; 12 | this.processorType = processorType; 13 | this.useDynamicEndpoint = useDynamicEndpoint; 14 | } 15 | 16 | @Override 17 | public boolean equals(Object obj) { 18 | ProducerInfo pi = (ProducerInfo) obj; 19 | return obj.getClass().equals(ProducerInfo.class) 20 | && this.endpointUri.equals(pi.endpointUri) 21 | && this.routeId.equals(pi.routeId) 22 | && this.processorType.equals(pi.processorType) 23 | && this.useDynamicEndpoint.equals(pi.useDynamicEndpoint); 24 | } 25 | 26 | @Override 27 | public String toString() { 28 | return "Producer in routeId \"".concat(routeId).concat("\" ") 29 | .concat("producing to ").concat(useDynamicEndpoint ? "dynamic " : "static ") 30 | .concat("URI \"").concat(endpointUri).concat("\" ") 31 | .concat("through processor \"").concat(processorType).concat("\""); 32 | } 33 | 34 | public Boolean getUseDynamicEndpoint() { 35 | return useDynamicEndpoint; 36 | } 37 | 38 | public String getProcessorType() { 39 | return processorType; 40 | } 41 | 42 | public String getRouteId() { 43 | return routeId; 44 | } 45 | 46 | public String getEndpointUri() { 47 | return endpointUri; 48 | } 49 | } -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/java/io/github/ncasaux/camelplantuml/utils/EndpointUtils.java: -------------------------------------------------------------------------------- 1 | package io.github.ncasaux.camelplantuml.utils; 2 | 3 | import io.github.ncasaux.camelplantuml.model.EndpointBaseUriInfo; 4 | import org.apache.commons.codec.digest.DigestUtils; 5 | import org.slf4j.Logger; 6 | 7 | import java.io.UnsupportedEncodingException; 8 | import java.net.URI; 9 | import java.net.URISyntaxException; 10 | import java.net.URLDecoder; 11 | import java.util.HashMap; 12 | 13 | public class EndpointUtils { 14 | 15 | public static String getEndpointBaseUri(String endpointUri, Logger LOGGER) throws URISyntaxException, UnsupportedEncodingException { 16 | 17 | URI uri = new URI(endpointUri); 18 | String endpointBaseUri = new URI( 19 | uri.getScheme(), 20 | uri.getAuthority(), 21 | uri.getPath(), 22 | null, 23 | uri.getFragment()).toString(); 24 | 25 | LOGGER.debug("EndpointBaseUri \"{}\" built from EndpointUri \"{}\"", 26 | URLDecoder.decode(endpointBaseUri, "UTF-8"), 27 | URLDecoder.decode(endpointUri, "UTF-8")); 28 | 29 | return endpointBaseUri; 30 | } 31 | 32 | public static void addEndpointBaseUriInfo(HashMap endpointBaseUrisInfo, 33 | String endpointBaseUri, 34 | EndpointBaseUriInfo endpointBaseUriInfo, 35 | Logger LOGGER) { 36 | 37 | endpointBaseUriInfo.setDiagramElementId("endpoint_".concat(DigestUtils.md5Hex(endpointBaseUri))); 38 | 39 | if (!endpointBaseUrisInfo.containsKey(endpointBaseUri)) { 40 | endpointBaseUrisInfo.put(endpointBaseUri, endpointBaseUriInfo); 41 | LOGGER.info("EndpointBaseUri with id \"{}\" added to the map of endpointBaseUris", endpointBaseUri); 42 | } else { 43 | LOGGER.info("EndpointBaseUri with id \"{}\" already in the map of endpointBaseUris", endpointBaseUri); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/java/io/github/ncasaux/camelplantuml/extractor/processor/SendDynamicProcessorInfoExtractor.java: -------------------------------------------------------------------------------- 1 | package io.github.ncasaux.camelplantuml.extractor.processor; 2 | 3 | import io.github.ncasaux.camelplantuml.model.ProducerInfo; 4 | import io.github.ncasaux.camelplantuml.utils.ProducerUtils; 5 | import org.apache.commons.collections4.CollectionUtils; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import javax.management.*; 10 | import java.io.IOException; 11 | import java.net.URLDecoder; 12 | import java.util.ArrayList; 13 | import java.util.Collections; 14 | import java.util.List; 15 | import java.util.Set; 16 | 17 | public class SendDynamicProcessorInfoExtractor { 18 | 19 | private static final Logger LOGGER = LoggerFactory.getLogger(SendDynamicProcessorInfoExtractor.class); 20 | 21 | public static void getProcessorsInfo(MBeanServerConnection mbeanServer, 22 | ArrayList producersInfo) 23 | throws MalformedObjectNameException, AttributeNotFoundException, MBeanException, ReflectionException, InstanceNotFoundException, IOException { 24 | 25 | QueryExp exp = Query.eq(Query.classattr(), Query.value("org.apache.camel.management.mbean.ManagedSendDynamicProcessor")); 26 | Set processorsSet = mbeanServer.queryNames(new ObjectName("org.apache.camel:type=processors,*"), exp); 27 | List processorsList = new ArrayList<>(); 28 | 29 | CollectionUtils.addAll(processorsList, processorsSet); 30 | Collections.sort(processorsList); 31 | 32 | for (ObjectName on : processorsList) { 33 | String processorId = (String) mbeanServer.getAttribute(on, "ProcessorId"); 34 | LOGGER.debug("Processing processorId \"{}\"", processorId); 35 | 36 | String routeId = (String) mbeanServer.getAttribute(on, "RouteId"); 37 | 38 | ProducerInfo producerInfo = new ProducerInfo(routeId, URLDecoder.decode((String) mbeanServer.getAttribute(on, "Uri"), "UTF-8"), "toD", true); 39 | ProducerUtils.addProducerInfo(producersInfo, producerInfo, LOGGER); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /camel-plantuml-zip/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | camel-plantuml 7 | io.github.ncasaux 8 | 1.8.0 9 | 10 | 4.0.0 11 | 12 | camel-plantuml-zip 13 | jar 14 | 15 | 16 | 17 | io.github.ncasaux 18 | camel-plantuml-jar 19 | ${project.version} 20 | 21 | 22 | 23 | 24 | 25 | org.apache.maven.plugins 26 | maven-jar-plugin 27 | 3.3.0 28 | 29 | 30 | 31 | true 32 | lib 33 | io.github.ncasaux.CamelPlantUml 34 | 35 | 36 | 37 | 38 | 39 | org.apache.maven.plugins 40 | maven-assembly-plugin 41 | 3.6.0 42 | 43 | 44 | package 45 | 46 | single 47 | 48 | 49 | false 50 | 51 | src/main/assembly/zip.xml 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/java/io/github/ncasaux/camelplantuml/routebuilder/CamelPlantUmlRouteBuilder.java: -------------------------------------------------------------------------------- 1 | package io.github.ncasaux.camelplantuml.routebuilder; 2 | 3 | import io.github.ncasaux.camelplantuml.processor.GetRoutesInfoProcessor; 4 | import io.github.ncasaux.camelplantuml.utils.JmxUtils; 5 | import org.apache.camel.builder.endpoint.EndpointRouteBuilder; 6 | import org.apache.camel.model.rest.RestParamType; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import javax.management.remote.JMXConnector; 11 | import java.io.IOException; 12 | 13 | public class CamelPlantUmlRouteBuilder extends EndpointRouteBuilder { 14 | 15 | private static final Logger LOGGER = LoggerFactory.getLogger(CamelPlantUmlRouteBuilder.class); 16 | 17 | private Integer port = 8090; 18 | private String host = "localhost"; 19 | private final String jmxHost = System.getProperty("jmxHost"); 20 | 21 | /** 22 | * Creates a Camel RouteBuilder for camel-plantuml using default host and port for the HTTP endpoint 23 | */ 24 | public CamelPlantUmlRouteBuilder() { 25 | } 26 | 27 | /** 28 | * Creates a Camel RouteBuilder for camel-plantuml using specified host and port for the HTTP endpoint 29 | * 30 | * @param host Host of the HTTP endpoint of camel-plantuml 31 | * @param port Port of the HTTP endpoint of camel-plantuml 32 | */ 33 | public CamelPlantUmlRouteBuilder(String host, Integer port) { 34 | this.port = port; 35 | this.host = host; 36 | } 37 | 38 | public void configure() throws IOException { 39 | 40 | if (jmxHost != null) { 41 | LOGGER.info("Testing MBean server connection from provided jmxHost \"".concat(jmxHost).concat("\"")); 42 | JMXConnector connector = JmxUtils.getConnector(jmxHost); 43 | connector.getMBeanServerConnection(); 44 | connector.close(); 45 | LOGGER.info("MBean server connection successfully tested"); 46 | } 47 | 48 | restConfiguration().component("netty-http").host(host).port(port); 49 | 50 | rest("camel-plantuml") 51 | .get("diagram.puml") 52 | .param().name("connectRoutes").type(RestParamType.query).defaultValue("false").endParam() 53 | .to("direct:camel-plantuml-generate-plantuml") 54 | ; 55 | 56 | from("direct:camel-plantuml-generate-plantuml").routeId("camel-plantuml-http-trigger") 57 | .process(new GetRoutesInfoProcessor()) 58 | ; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/java/io/github/ncasaux/camelplantuml/extractor/processor/SendProcessorInfoExtractor.java: -------------------------------------------------------------------------------- 1 | package io.github.ncasaux.camelplantuml.extractor.processor; 2 | 3 | import io.github.ncasaux.camelplantuml.model.EndpointBaseUriInfo; 4 | import io.github.ncasaux.camelplantuml.model.ProducerInfo; 5 | import io.github.ncasaux.camelplantuml.utils.EndpointUtils; 6 | import io.github.ncasaux.camelplantuml.utils.ProducerUtils; 7 | import org.apache.camel.util.URISupport; 8 | import org.apache.commons.collections4.CollectionUtils; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | import javax.management.*; 13 | import java.io.IOException; 14 | import java.net.URISyntaxException; 15 | import java.net.URLDecoder; 16 | import java.util.*; 17 | 18 | public class SendProcessorInfoExtractor { 19 | 20 | private static final Logger LOGGER = LoggerFactory.getLogger(SendProcessorInfoExtractor.class); 21 | 22 | public static void getProcessorsInfo(MBeanServerConnection mbeanServer, 23 | ArrayList producersInfo, 24 | HashMap endpointBaseUrisInfo) 25 | throws MalformedObjectNameException, AttributeNotFoundException, MBeanException, ReflectionException, InstanceNotFoundException, URISyntaxException, IOException { 26 | 27 | QueryExp exp = Query.eq(Query.classattr(), Query.value("org.apache.camel.management.mbean.ManagedSendProcessor")); 28 | Set processorsSet = mbeanServer.queryNames(new ObjectName("org.apache.camel:type=processors,*"), exp); 29 | List processorsList = new ArrayList<>(); 30 | 31 | CollectionUtils.addAll(processorsList, processorsSet); 32 | Collections.sort(processorsList); 33 | 34 | for (ObjectName on : processorsList) { 35 | String processorId = (String) mbeanServer.getAttribute(on, "ProcessorId"); 36 | LOGGER.debug("Processing processorId \"{}\"", processorId); 37 | 38 | String routeId = (String) mbeanServer.getAttribute(on, "RouteId"); 39 | String destination = (String) mbeanServer.getAttribute(on, "Destination"); 40 | String normalizedUri = URISupport.normalizeUri(destination); 41 | String endpointBaseUri = URLDecoder.decode(EndpointUtils.getEndpointBaseUri(normalizedUri, LOGGER), "UTF-8"); 42 | 43 | ProducerInfo producerInfo = new ProducerInfo(routeId, endpointBaseUri, "to", false); 44 | ProducerUtils.addProducerInfoIfNotInList(producersInfo, producerInfo, LOGGER); 45 | 46 | EndpointBaseUriInfo endpointBaseUriInfo = new EndpointBaseUriInfo(); 47 | EndpointUtils.addEndpointBaseUriInfo(endpointBaseUrisInfo, endpointBaseUri, endpointBaseUriInfo, LOGGER); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/java/io/github/ncasaux/camelplantuml/extractor/RoutesInfoExtractor.java: -------------------------------------------------------------------------------- 1 | package io.github.ncasaux.camelplantuml.extractor; 2 | 3 | import io.github.ncasaux.camelplantuml.model.ConsumerInfo; 4 | import io.github.ncasaux.camelplantuml.model.EndpointBaseUriInfo; 5 | import io.github.ncasaux.camelplantuml.model.RouteInfo; 6 | import io.github.ncasaux.camelplantuml.utils.ConsumerUtils; 7 | import io.github.ncasaux.camelplantuml.utils.EndpointUtils; 8 | import io.github.ncasaux.camelplantuml.utils.RouteUtils; 9 | import org.apache.camel.support.EndpointHelper; 10 | import org.apache.commons.collections4.CollectionUtils; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | import javax.management.MBeanServerConnection; 15 | import javax.management.ObjectName; 16 | import java.net.URLDecoder; 17 | import java.util.*; 18 | 19 | public class RoutesInfoExtractor { 20 | 21 | private static final Logger LOGGER = LoggerFactory.getLogger(RoutesInfoExtractor.class); 22 | 23 | public static void getRoutesInfo(MBeanServerConnection mbeanServer, 24 | HashMap routesInfo, 25 | ArrayList consumersInfo, 26 | HashMap endpointBaseUrisInfo) throws Exception { 27 | 28 | Set routesSet = mbeanServer.queryNames(new ObjectName("org.apache.camel:type=routes,*"), null); 29 | List routesList = new ArrayList<>(); 30 | 31 | CollectionUtils.addAll(routesList, routesSet); 32 | Collections.sort(routesList); 33 | 34 | for (ObjectName on : routesList) { 35 | String routeState = (String) mbeanServer.getAttribute(on, "State"); 36 | String routeId = (String) mbeanServer.getAttribute(on, "RouteId"); 37 | 38 | LOGGER.debug("Processing routeId \"{}\"", routeId); 39 | if (!routeState.equalsIgnoreCase("Started")) { 40 | LOGGER.warn("Route with id \"{}\" is not started, associated processors may not have been created, diagram may be incomplete", routeId); 41 | } 42 | 43 | String endpointUri = (String) mbeanServer.getAttribute(on, "EndpointUri"); 44 | String normalizedUri = EndpointHelper.normalizeEndpointUri(endpointUri); 45 | String endpointBaseUri = URLDecoder.decode(EndpointUtils.getEndpointBaseUri(normalizedUri, LOGGER), "UTF-8"); 46 | String description = (String) mbeanServer.getAttribute(on, "Description"); 47 | 48 | RouteInfo routeInfo = new RouteInfo(endpointBaseUri, description); 49 | RouteUtils.addRouteInfo(routesInfo, routeId, routeInfo, LOGGER); 50 | 51 | ConsumerInfo consumerInfo = new ConsumerInfo(routeId, endpointBaseUri, "from", false); 52 | ConsumerUtils.addConsumerInfo(consumersInfo, consumerInfo, LOGGER); 53 | 54 | EndpointBaseUriInfo endpointBaseUriInfo = new EndpointBaseUriInfo(); 55 | EndpointUtils.addEndpointBaseUriInfo(endpointBaseUrisInfo, endpointBaseUri, endpointBaseUriInfo, LOGGER); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/java/io/github/ncasaux/camelplantuml/extractor/processor/WireTapProcessorInfoExtractor.java: -------------------------------------------------------------------------------- 1 | package io.github.ncasaux.camelplantuml.extractor.processor; 2 | 3 | import io.github.ncasaux.camelplantuml.model.EndpointBaseUriInfo; 4 | import io.github.ncasaux.camelplantuml.model.ProducerInfo; 5 | import io.github.ncasaux.camelplantuml.utils.EndpointUtils; 6 | import io.github.ncasaux.camelplantuml.utils.ProducerUtils; 7 | import org.apache.camel.support.EndpointHelper; 8 | import org.apache.commons.collections4.CollectionUtils; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | import javax.management.*; 13 | import java.io.IOException; 14 | import java.net.URISyntaxException; 15 | import java.net.URLDecoder; 16 | import java.util.*; 17 | 18 | public class WireTapProcessorInfoExtractor { 19 | 20 | private static final Logger LOGGER = LoggerFactory.getLogger(WireTapProcessorInfoExtractor.class); 21 | 22 | public static void getProcessorsInfo(MBeanServerConnection mbeanServer, 23 | ArrayList producersInfo, 24 | HashMap endpointBaseUrisInfo) 25 | throws MalformedObjectNameException, AttributeNotFoundException, MBeanException, ReflectionException, InstanceNotFoundException, URISyntaxException, IOException { 26 | 27 | QueryExp exp = Query.eq(Query.classattr(), Query.value("org.apache.camel.management.mbean.ManagedWireTapProcessor")); 28 | Set processorsSet = mbeanServer.queryNames(new ObjectName("org.apache.camel:type=processors,*"), exp); 29 | List processorsList = new ArrayList<>(); 30 | 31 | CollectionUtils.addAll(processorsList, processorsSet); 32 | Collections.sort(processorsList); 33 | 34 | for (ObjectName on : processorsList) { 35 | String processorId = (String) mbeanServer.getAttribute(on, "ProcessorId"); 36 | LOGGER.debug("Processing processorId \"{}\"", processorId); 37 | 38 | String routeId = (String) mbeanServer.getAttribute(on, "RouteId"); 39 | String normalizedUri = EndpointHelper.normalizeEndpointUri((String) mbeanServer.getAttribute(on, "Uri")); 40 | 41 | if ((boolean) mbeanServer.getAttribute(on, "DynamicUri")) { 42 | String endpointUri = URLDecoder.decode(normalizedUri, "UTF-8"); 43 | 44 | ProducerInfo producerInfo = new ProducerInfo(routeId, endpointUri, "wiretap", true); 45 | ProducerUtils.addProducerInfo(producersInfo, producerInfo, LOGGER); 46 | 47 | } else { 48 | String endpointBaseUri = URLDecoder.decode(EndpointUtils.getEndpointBaseUri(normalizedUri, LOGGER), "UTF-8"); 49 | 50 | ProducerInfo producerInfo = new ProducerInfo(routeId, endpointBaseUri, "wiretap", false); 51 | ProducerUtils.addProducerInfoIfNotInList(producersInfo, producerInfo, LOGGER); 52 | 53 | EndpointBaseUriInfo endpointBaseUriInfo = new EndpointBaseUriInfo(); 54 | EndpointUtils.addEndpointBaseUriInfo(endpointBaseUrisInfo, endpointBaseUri, endpointBaseUriInfo, LOGGER); 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/java/io/github/ncasaux/camelplantuml/extractor/processor/EnricherInfoExtractor.java: -------------------------------------------------------------------------------- 1 | package io.github.ncasaux.camelplantuml.extractor.processor; 2 | 3 | import io.github.ncasaux.camelplantuml.model.EndpointBaseUriInfo; 4 | import io.github.ncasaux.camelplantuml.model.ProducerInfo; 5 | import io.github.ncasaux.camelplantuml.utils.EndpointUtils; 6 | import io.github.ncasaux.camelplantuml.utils.ProducerUtils; 7 | import org.apache.camel.support.EndpointHelper; 8 | import org.apache.commons.collections4.CollectionUtils; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | import javax.management.*; 13 | import java.io.IOException; 14 | import java.net.URISyntaxException; 15 | import java.net.URLDecoder; 16 | import java.util.*; 17 | 18 | public class EnricherInfoExtractor { 19 | 20 | private static final Logger LOGGER = LoggerFactory.getLogger(EnricherInfoExtractor.class); 21 | 22 | public static void getProcessorsInfo(MBeanServerConnection mbeanServer, 23 | ArrayList producersInfo, 24 | HashMap endpointBaseUrisInfo) 25 | throws MalformedObjectNameException, AttributeNotFoundException, MBeanException, ReflectionException, InstanceNotFoundException, URISyntaxException, IOException { 26 | 27 | QueryExp exp = Query.eq(Query.classattr(), Query.value("org.apache.camel.management.mbean.ManagedEnricher")); 28 | Set processorsSet = mbeanServer.queryNames(new ObjectName("org.apache.camel:type=processors,*"), exp); 29 | List processorsList = new ArrayList<>(); 30 | 31 | CollectionUtils.addAll(processorsList, processorsSet); 32 | Collections.sort(processorsList); 33 | 34 | for (ObjectName on : processorsList) { 35 | String processorId = (String) mbeanServer.getAttribute(on, "ProcessorId"); 36 | LOGGER.debug("Processing processorId \"{}\"", processorId); 37 | 38 | String routeId = (String) mbeanServer.getAttribute(on, "RouteId"); 39 | String expression = (String) mbeanServer.getAttribute(on, "Expression"); 40 | String expressionLanguage = (String) mbeanServer.getAttribute(on, "ExpressionLanguage"); 41 | String normalizedUri = EndpointHelper.normalizeEndpointUri(expression); 42 | 43 | if (expressionLanguage.equalsIgnoreCase("constant")) { 44 | String endpointBaseUri = URLDecoder.decode(EndpointUtils.getEndpointBaseUri(normalizedUri, LOGGER), "UTF-8"); 45 | 46 | ProducerInfo producerInfo = new ProducerInfo(routeId, endpointBaseUri, "enrich", false); 47 | ProducerUtils.addProducerInfoIfNotInList(producersInfo, producerInfo, LOGGER); 48 | 49 | EndpointBaseUriInfo endpointBaseUriInfo = new EndpointBaseUriInfo(); 50 | EndpointUtils.addEndpointBaseUriInfo(endpointBaseUrisInfo, endpointBaseUri, endpointBaseUriInfo, LOGGER); 51 | 52 | } else if (expressionLanguage.equalsIgnoreCase("simple")) { 53 | String endpointUri = URLDecoder.decode(normalizedUri, "UTF-8"); 54 | 55 | ProducerInfo producerInfo = new ProducerInfo(routeId, endpointUri, "enrich", true); 56 | ProducerUtils.addProducerInfo(producersInfo, producerInfo, LOGGER); 57 | 58 | } else { 59 | LOGGER.info("Expression \"{}({})\" can not be used to get an URI", expressionLanguage, expression); 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/java/io/github/ncasaux/camelplantuml/extractor/processor/PollEnricherInfoExtractor.java: -------------------------------------------------------------------------------- 1 | package io.github.ncasaux.camelplantuml.extractor.processor; 2 | 3 | import io.github.ncasaux.camelplantuml.model.ConsumerInfo; 4 | import io.github.ncasaux.camelplantuml.model.EndpointBaseUriInfo; 5 | import io.github.ncasaux.camelplantuml.utils.ConsumerUtils; 6 | import io.github.ncasaux.camelplantuml.utils.EndpointUtils; 7 | import org.apache.camel.support.EndpointHelper; 8 | import org.apache.commons.collections4.CollectionUtils; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | import javax.management.*; 13 | import java.io.IOException; 14 | import java.net.URISyntaxException; 15 | import java.net.URLDecoder; 16 | import java.util.*; 17 | 18 | public class PollEnricherInfoExtractor { 19 | 20 | private static final Logger LOGGER = LoggerFactory.getLogger(PollEnricherInfoExtractor.class); 21 | 22 | public static void getProcessorsInfo(MBeanServerConnection mbeanServer, 23 | ArrayList consumersInfo, 24 | HashMap endpointBaseUrisInfo) 25 | throws MalformedObjectNameException, AttributeNotFoundException, MBeanException, ReflectionException, InstanceNotFoundException, URISyntaxException, IOException { 26 | 27 | QueryExp exp = Query.eq(Query.classattr(), Query.value("org.apache.camel.management.mbean.ManagedPollEnricher")); 28 | Set processorsSet = mbeanServer.queryNames(new ObjectName("org.apache.camel:type=processors,*"), exp); 29 | List processorsList = new ArrayList<>(); 30 | 31 | CollectionUtils.addAll(processorsList, processorsSet); 32 | Collections.sort(processorsList); 33 | 34 | for (ObjectName on : processorsList) { 35 | String processorId = (String) mbeanServer.getAttribute(on, "ProcessorId"); 36 | LOGGER.debug("Processing processorId \"{}\"", processorId); 37 | 38 | String routeId = (String) mbeanServer.getAttribute(on, "RouteId"); 39 | String expression = (String) mbeanServer.getAttribute(on, "Expression"); 40 | String expressionLanguage = (String) mbeanServer.getAttribute(on, "ExpressionLanguage"); 41 | String normalizedUri = EndpointHelper.normalizeEndpointUri(expression); 42 | 43 | if (expressionLanguage.equalsIgnoreCase("constant")) { 44 | String endpointBaseUri = URLDecoder.decode(EndpointUtils.getEndpointBaseUri(normalizedUri, LOGGER), "UTF-8"); 45 | 46 | ConsumerInfo consumerInfo = new ConsumerInfo(routeId, endpointBaseUri, "pollEnrich", false); 47 | ConsumerUtils.addConsumerInfo(consumersInfo, consumerInfo, LOGGER); 48 | 49 | EndpointBaseUriInfo endpointBaseUriInfo = new EndpointBaseUriInfo(); 50 | EndpointUtils.addEndpointBaseUriInfo(endpointBaseUrisInfo, endpointBaseUri, endpointBaseUriInfo, LOGGER); 51 | 52 | } else if (expressionLanguage.equalsIgnoreCase("simple")) { 53 | String endpointUri = URLDecoder.decode(normalizedUri, "UTF-8"); 54 | 55 | ConsumerInfo consumerInfo = new ConsumerInfo(routeId, endpointUri, "pollEnrich", true); 56 | ConsumerUtils.addConsumerInfo(consumersInfo, consumerInfo, LOGGER); 57 | 58 | } else { 59 | LOGGER.info("Expression \"{}({})\" can not be used to get an URI", expressionLanguage, expression); 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/java/io/github/ncasaux/camelplantuml/generator/EndpointsDiagramGenerator.java: -------------------------------------------------------------------------------- 1 | package io.github.ncasaux.camelplantuml.generator; 2 | 3 | import io.github.ncasaux.camelplantuml.model.ConsumerInfo; 4 | import io.github.ncasaux.camelplantuml.model.EndpointBaseUriInfo; 5 | import io.github.ncasaux.camelplantuml.model.ProducerInfo; 6 | import io.github.ncasaux.camelplantuml.model.query.Parameters; 7 | import io.github.ncasaux.camelplantuml.processor.GetRoutesInfoProcessor; 8 | import org.apache.commons.io.IOUtils; 9 | import org.apache.commons.lang3.StringUtils; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | 13 | import java.io.IOException; 14 | import java.net.URI; 15 | import java.net.URISyntaxException; 16 | import java.nio.charset.StandardCharsets; 17 | import java.util.*; 18 | 19 | public class EndpointsDiagramGenerator { 20 | 21 | private static final Logger LOGGER = LoggerFactory.getLogger(EndpointsDiagramGenerator.class); 22 | 23 | public static String generateUmlString(ArrayList consumersInfo, 24 | ArrayList producersInfo, 25 | HashMap endpointBaseUrisInfo, 26 | Parameters parameters) throws IOException, URISyntaxException { 27 | 28 | String umlEndpointTemplate = IOUtils.toString(Objects.requireNonNull(EndpointsDiagramGenerator.class.getClassLoader().getResourceAsStream("plantuml/endpointTemplate")), StandardCharsets.UTF_8); 29 | String umlString = ""; 30 | 31 | for (Map.Entry endpointBaseUriInfoEntry : endpointBaseUrisInfo.entrySet()) { 32 | String endpointBaseUri = endpointBaseUriInfoEntry.getKey(); 33 | String diagramElementId = endpointBaseUriInfoEntry.getValue().getDiagramElementId(); 34 | 35 | boolean endpointHasConsumer = consumersInfo.stream().anyMatch(consumerInfo -> consumerInfo.getEndpointUri().equals(endpointBaseUri)); 36 | boolean endpointHasProducer = producersInfo.stream().anyMatch(producerInfo -> producerInfo.getEndpointUri().equals(endpointBaseUri)); 37 | boolean drawEndpoint = true; 38 | 39 | for (String filter : GetRoutesInfoProcessor.endpointBaseUriFilters) { 40 | if (endpointBaseUri.matches(filter)) { 41 | drawEndpoint = false; 42 | LOGGER.info("EndpointBaseUri \"{}\" matches the endpoint filter \"{}\", endpoint will not be part of the diagram", endpointBaseUri, filter); 43 | break; 44 | } 45 | } 46 | 47 | if (parameters.uriFilterPattern().matcher(endpointBaseUri).matches()) { 48 | drawEndpoint = false; 49 | LOGGER.info("EndpointBaseUri \"{}\" matches the uriFilterPattern \"{}\", endpoint will not be part of the diagram", endpointBaseUri, parameters.uriFilterPattern()); 50 | } 51 | 52 | if (parameters.connectRoutes() && endpointHasConsumer && endpointHasProducer && Arrays.asList(GetRoutesInfoProcessor.camelInternalEndpointSchemeFilters).contains(new URI(endpointBaseUri).getScheme())) { 53 | drawEndpoint = false; 54 | LOGGER.info("Parameter \"connectRoutes\" is \"true\", endpointBaseUri \"{}\" is internal and has both consumer and producer, endpoint will not be part of the diagram", endpointBaseUri); 55 | } 56 | 57 | if (drawEndpoint) { 58 | umlString = umlString 59 | .concat(StringUtils.replaceEach(umlEndpointTemplate, 60 | new String[]{"%%endpointBaseUri%%", "%%endpointElementId%%"}, 61 | new String[]{endpointBaseUri, diagramElementId})) 62 | .concat("\n\n") 63 | ; 64 | } 65 | } 66 | return umlString; 67 | } 68 | } -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/java/io/github/ncasaux/camelplantuml/extractor/processor/RecipientListInfoExtractor.java: -------------------------------------------------------------------------------- 1 | package io.github.ncasaux.camelplantuml.extractor.processor; 2 | 3 | import io.github.ncasaux.camelplantuml.model.EndpointBaseUriInfo; 4 | import io.github.ncasaux.camelplantuml.model.ProducerInfo; 5 | import io.github.ncasaux.camelplantuml.utils.EndpointUtils; 6 | import io.github.ncasaux.camelplantuml.utils.ProducerUtils; 7 | import org.apache.camel.support.EndpointHelper; 8 | import org.apache.commons.collections4.CollectionUtils; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | import javax.management.*; 13 | import java.io.IOException; 14 | import java.net.URISyntaxException; 15 | import java.net.URLDecoder; 16 | import java.util.*; 17 | 18 | public class RecipientListInfoExtractor { 19 | 20 | private static final Logger LOGGER = LoggerFactory.getLogger(RecipientListInfoExtractor.class); 21 | 22 | public static void getProcessorsInfo(MBeanServerConnection mbeanServer, 23 | ArrayList producersInfo, 24 | HashMap endpointBaseUrisInfo) 25 | throws MalformedObjectNameException, AttributeNotFoundException, MBeanException, ReflectionException, InstanceNotFoundException, URISyntaxException, IOException { 26 | 27 | QueryExp exp = Query.eq(Query.classattr(), Query.value("org.apache.camel.management.mbean.ManagedRecipientList")); 28 | Set processorsSet = mbeanServer.queryNames(new ObjectName("org.apache.camel:type=processors,*"), exp); 29 | List processorsList = new ArrayList<>(); 30 | 31 | CollectionUtils.addAll(processorsList, processorsSet); 32 | Collections.sort(processorsList); 33 | 34 | for (ObjectName on : processorsList) { 35 | String processorId = (String) mbeanServer.getAttribute(on, "ProcessorId"); 36 | LOGGER.debug("Processing processorId \"{}\"", processorId); 37 | 38 | String routeId = (String) mbeanServer.getAttribute(on, "RouteId"); 39 | String expression = (String) mbeanServer.getAttribute(on, "Expression"); 40 | String expressionLanguage = (String) mbeanServer.getAttribute(on, "ExpressionLanguage"); 41 | String uriDelimiter = (String) mbeanServer.getAttribute(on, "UriDelimiter"); 42 | String[] recipientList = expression.split(uriDelimiter); 43 | 44 | if (expressionLanguage.equalsIgnoreCase("constant")) { 45 | for (String recipient : recipientList) { 46 | String normalizedUri = EndpointHelper.normalizeEndpointUri(recipient); 47 | String endpointBaseUri = URLDecoder.decode(EndpointUtils.getEndpointBaseUri(normalizedUri, LOGGER), "UTF-8"); 48 | 49 | ProducerInfo producerInfo = new ProducerInfo(routeId, endpointBaseUri, "recipientList", false); 50 | ProducerUtils.addProducerInfoIfNotInList(producersInfo, producerInfo, LOGGER); 51 | 52 | EndpointBaseUriInfo endpointBaseUriInfo = new EndpointBaseUriInfo(); 53 | EndpointUtils.addEndpointBaseUriInfo(endpointBaseUrisInfo, endpointBaseUri, endpointBaseUriInfo, LOGGER); 54 | } 55 | 56 | } else if (expressionLanguage.equalsIgnoreCase("simple")) { 57 | for (String recipient : recipientList) { 58 | String normalizedUri = EndpointHelper.normalizeEndpointUri(recipient); 59 | String endpointUri = URLDecoder.decode(normalizedUri, "UTF-8"); 60 | 61 | ProducerInfo producerInfo = new ProducerInfo(routeId, endpointUri, "recipientList", true); 62 | ProducerUtils.addProducerInfo(producersInfo, producerInfo, LOGGER); 63 | } 64 | 65 | } else { 66 | LOGGER.info("Expression \"{}({})\" can not be used to get an URI", expressionLanguage, expression); 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/java/io/github/ncasaux/camelplantuml/generator/RoutesDiagramGenerator.java: -------------------------------------------------------------------------------- 1 | package io.github.ncasaux.camelplantuml.generator; 2 | 3 | import io.github.ncasaux.camelplantuml.model.RouteInfo; 4 | import io.github.ncasaux.camelplantuml.model.query.Parameters; 5 | import io.github.ncasaux.camelplantuml.processor.GetRoutesInfoProcessor; 6 | import org.apache.commons.io.IOUtils; 7 | import org.apache.commons.lang3.StringUtils; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import java.io.IOException; 12 | import java.nio.charset.StandardCharsets; 13 | import java.util.HashMap; 14 | import java.util.Map; 15 | import java.util.Objects; 16 | 17 | public class RoutesDiagramGenerator { 18 | 19 | private static final Logger LOGGER = LoggerFactory.getLogger(RoutesDiagramGenerator.class); 20 | 21 | public static String generateUmlString(HashMap routesInfo, Parameters parameters) throws IOException { 22 | 23 | String umlRouteTemplate = IOUtils.toString(Objects.requireNonNull(RoutesDiagramGenerator.class.getClassLoader().getResourceAsStream("plantuml/routeTemplate")), StandardCharsets.UTF_8); 24 | String umlRouteTemplateNoDescription = IOUtils.toString(Objects.requireNonNull(RoutesDiagramGenerator.class.getClassLoader().getResourceAsStream("plantuml/routeTemplateNoDescription")), StandardCharsets.UTF_8); 25 | String umlString = ""; 26 | 27 | for (Map.Entry routeInfoEntry : routesInfo.entrySet()) { 28 | String routeId = routeInfoEntry.getKey(); 29 | String diagramElementId = routeInfoEntry.getValue().getDiagramElementId(); 30 | String routeDescription = routeInfoEntry.getValue().getDescription(); 31 | String routeEndpointBaseUri = routeInfoEntry.getValue().getEndpointBaseUri(); 32 | 33 | boolean drawRoute = true; 34 | 35 | for (String routeIdFilter : GetRoutesInfoProcessor.routeIdFilters) { 36 | if (routeId.matches(routeIdFilter)) { 37 | drawRoute = false; 38 | LOGGER.info("Route with id \"{}\" matches the routeId filter \"{}\", route will not be part of the diagram", routeId, routeIdFilter); 39 | break; 40 | } 41 | } 42 | 43 | for (String endpointBaseUriFilter : GetRoutesInfoProcessor.endpointBaseUriFilters) { 44 | if (routeEndpointBaseUri.matches(endpointBaseUriFilter)) { 45 | drawRoute = false; 46 | LOGGER.info("Route with id \"{}\" matches the endpoint filter \"{}\", route will not be part of the diagram", routeId, endpointBaseUriFilter); 47 | break; 48 | } 49 | } 50 | 51 | if (parameters.uriFilterPattern().matcher(routeEndpointBaseUri).matches()) { 52 | drawRoute = false; 53 | LOGGER.info("Route with id \"{}\" and routeEndpointBaseUri \"{}\" matches the uriFilterPattern \"{}\", " + 54 | "route will not be part of the diagram", routeId, routeEndpointBaseUri, parameters.uriFilterPattern()); 55 | } 56 | 57 | if (drawRoute) { 58 | if (routeDescription == null || routeDescription.isEmpty()) { 59 | umlString = umlString 60 | .concat(StringUtils.replaceEach(umlRouteTemplateNoDescription, 61 | new String[]{"%%routeId%%", "%%routeElementId%%", "%%routeDescription%%"}, 62 | new String[]{routeId, diagramElementId, routeDescription})) 63 | .concat("\n\n"); 64 | } else { 65 | umlString = umlString 66 | .concat(StringUtils.replaceEach(umlRouteTemplate, 67 | new String[]{"%%routeId%%", "%%routeElementId%%", "%%routeDescription%%"}, 68 | new String[]{routeId, diagramElementId, routeDescription})) 69 | .concat("\n\n"); 70 | } 71 | } 72 | } 73 | return umlString; 74 | } 75 | } 76 | 77 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/test/java/Enricher/EnricherHeaderTest.java: -------------------------------------------------------------------------------- 1 | package Enricher; 2 | 3 | import io.github.ncasaux.camelplantuml.routebuilder.CamelPlantUmlRouteBuilder; 4 | import org.apache.camel.RoutesBuilder; 5 | import org.apache.camel.builder.AdviceWith; 6 | import org.apache.camel.builder.RouteBuilder; 7 | import org.apache.camel.component.mock.MockEndpoint; 8 | import org.apache.camel.test.junit5.CamelTestSupport; 9 | import org.junit.jupiter.api.Test; 10 | 11 | import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.*; 12 | 13 | public class EnricherHeaderTest extends CamelTestSupport { 14 | 15 | @Override 16 | public boolean isUseAdviceWith() { 17 | return true; 18 | } 19 | 20 | @Override 21 | public boolean useJmx() { 22 | return true; 23 | } 24 | 25 | @Test 26 | public void testMock() throws Exception { 27 | MockEndpoint mock = getMockEndpoint("mock:camel-plantuml-output"); 28 | 29 | 30 | mock.expectedBodiesReceived("@startuml\n" + 31 | "\n" + 32 | "skinparam ArrowColor #Black\n" + 33 | "\n" + 34 | "skinparam rectangle {\n" + 35 | " RoundCorner 20\n" + 36 | "}\n" + 37 | "\n" + 38 | "skinparam rectangle<> {\n" + 39 | " BorderColor #6C8EBF\n" + 40 | " BackgroundColor #DAE8FC\n" + 41 | "}\n" + 42 | "\n" + 43 | "skinparam queue<> {\n" + 44 | "}\n" + 45 | "\n" + 46 | "skinparam queue<> {\n" + 47 | " BorderColor #B85450\n" + 48 | " BackgroundColor #F8CECC\n" + 49 | "}\n" + 50 | "\n" + 51 | "skinparam queue<> {\n" + 52 | " BorderColor #82B366\n" + 53 | " BackgroundColor #D5E8D4\n" + 54 | "}\n" + 55 | "\n" + 56 | "footer Generated with camel-plantuml on %date(\"dd-MM-yyyy HH:mm\")\n" + 57 | "\n" + 58 | "' === Some useful settings for tweaking diagram layout ===\n" + 59 | "'left to right direction\n" + 60 | "'hide stereotype\n" + 61 | "'skinparam nodesep 50\n" + 62 | "'skinparam ranksep 50\n" + 63 | "'skinparam wrapWidth 250\n" + 64 | "\n" + 65 | "rectangle route_796831ba0b2941f3ae7823de08843a7e <> as \"\n" + 66 | "enricherHeaderRoute1\n" + 67 | "\"\n" + 68 | "\n" + 69 | "queue endpoint_c1749b7ed34e5395932c33f971ca4151 <><> as \"\n" + 70 | "timer://foo\n" + 71 | "\"\n" + 72 | "\n" + 73 | "endpoint_c1749b7ed34e5395932c33f971ca4151 --> route_796831ba0b2941f3ae7823de08843a7e : from\n" + 74 | "\n" + 75 | "@enduml\n"); 76 | 77 | AdviceWith.adviceWith(context, "camel-plantuml-http-trigger", a -> { 78 | a.weaveAddLast().transform(a.body().regexReplaceAll("\r", "")); 79 | a.weaveAddLast().to("mock:camel-plantuml-output"); 80 | } 81 | ); 82 | 83 | context.start(); 84 | 85 | template.sendBody("direct:camel-plantuml-generate-plantuml", null); 86 | MockEndpoint.assertIsSatisfied(context); 87 | } 88 | 89 | @Override 90 | protected RoutesBuilder createRouteBuilder() { 91 | return new RouteBuilder() { 92 | @Override 93 | public void configure() throws Exception { 94 | from(timer("foo").period(5000)).routeId("enricherHeaderRoute1") 95 | .setHeader("dummyHeader", constant("mock://dummyEnricher")) 96 | .enrich().header("dummyHeader").id("_enrich01"); 97 | 98 | getContext().addRoutes(new CamelPlantUmlRouteBuilder()); 99 | 100 | } 101 | 102 | }; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/test/java/RecipientList/RecipientListHeaderTest.java: -------------------------------------------------------------------------------- 1 | package RecipientList; 2 | 3 | import io.github.ncasaux.camelplantuml.routebuilder.CamelPlantUmlRouteBuilder; 4 | import org.apache.camel.RoutesBuilder; 5 | import org.apache.camel.builder.AdviceWith; 6 | import org.apache.camel.builder.RouteBuilder; 7 | import org.apache.camel.component.mock.MockEndpoint; 8 | import org.apache.camel.test.junit5.CamelTestSupport; 9 | import org.junit.jupiter.api.Test; 10 | 11 | import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.timer; 12 | 13 | public class RecipientListHeaderTest extends CamelTestSupport { 14 | 15 | @Override 16 | public boolean isUseAdviceWith() { 17 | return true; 18 | } 19 | 20 | @Override 21 | public boolean useJmx() { 22 | return true; 23 | } 24 | 25 | @Test 26 | public void testMock() throws Exception { 27 | MockEndpoint mock = getMockEndpoint("mock:camel-plantuml-output"); 28 | 29 | 30 | mock.expectedBodiesReceived("@startuml\n" + 31 | "\n" + 32 | "skinparam ArrowColor #Black\n" + 33 | "\n" + 34 | "skinparam rectangle {\n" + 35 | " RoundCorner 20\n" + 36 | "}\n" + 37 | "\n" + 38 | "skinparam rectangle<> {\n" + 39 | " BorderColor #6C8EBF\n" + 40 | " BackgroundColor #DAE8FC\n" + 41 | "}\n" + 42 | "\n" + 43 | "skinparam queue<> {\n" + 44 | "}\n" + 45 | "\n" + 46 | "skinparam queue<> {\n" + 47 | " BorderColor #B85450\n" + 48 | " BackgroundColor #F8CECC\n" + 49 | "}\n" + 50 | "\n" + 51 | "skinparam queue<> {\n" + 52 | " BorderColor #82B366\n" + 53 | " BackgroundColor #D5E8D4\n" + 54 | "}\n" + 55 | "\n" + 56 | "footer Generated with camel-plantuml on %date(\"dd-MM-yyyy HH:mm\")\n" + 57 | "\n" + 58 | "' === Some useful settings for tweaking diagram layout ===\n" + 59 | "'left to right direction\n" + 60 | "'hide stereotype\n" + 61 | "'skinparam nodesep 50\n" + 62 | "'skinparam ranksep 50\n" + 63 | "'skinparam wrapWidth 250\n" + 64 | "\n" + 65 | "rectangle route_e640afceec0a6f7e24ae6310cfbc1516 <> as \"\n" + 66 | "recipientListHeaderRoute1\n" + 67 | "\"\n" + 68 | "\n" + 69 | "queue endpoint_c1749b7ed34e5395932c33f971ca4151 <><> as \"\n" + 70 | "timer://foo\n" + 71 | "\"\n" + 72 | "\n" + 73 | "endpoint_c1749b7ed34e5395932c33f971ca4151 --> route_e640afceec0a6f7e24ae6310cfbc1516 : from\n" + 74 | "\n" + 75 | "@enduml\n"); 76 | 77 | AdviceWith.adviceWith(context, "camel-plantuml-http-trigger", a -> { 78 | a.weaveAddLast().transform(a.body().regexReplaceAll("\r", "")); 79 | a.weaveAddLast().to("mock:camel-plantuml-output"); 80 | } 81 | ); 82 | 83 | context.start(); 84 | 85 | template.sendBody("direct:camel-plantuml-generate-plantuml", null); 86 | MockEndpoint.assertIsSatisfied(context); 87 | } 88 | 89 | @Override 90 | protected RoutesBuilder createRouteBuilder() { 91 | return new RouteBuilder() { 92 | @Override 93 | public void configure() throws Exception { 94 | from(timer("foo").period(5000)).routeId("recipientListHeaderRoute1") 95 | .setHeader("dummyHeader", constant("mock://dummyRecipient")) 96 | .recipientList().header("dummyHeader").id("_recipientList01"); 97 | 98 | getContext().addRoutes(new CamelPlantUmlRouteBuilder()); 99 | 100 | } 101 | 102 | }; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/test/java/PollEnricher/PollEnricherHeaderTest.java: -------------------------------------------------------------------------------- 1 | package PollEnricher; 2 | 3 | import io.github.ncasaux.camelplantuml.routebuilder.CamelPlantUmlRouteBuilder; 4 | import org.apache.camel.RoutesBuilder; 5 | import org.apache.camel.builder.AdviceWith; 6 | import org.apache.camel.builder.RouteBuilder; 7 | import org.apache.camel.component.mock.MockEndpoint; 8 | import org.apache.camel.test.junit5.CamelTestSupport; 9 | import org.junit.jupiter.api.Test; 10 | 11 | import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.mock; 12 | import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.timer; 13 | 14 | public class PollEnricherHeaderTest extends CamelTestSupport { 15 | 16 | @Override 17 | public boolean isUseAdviceWith() { 18 | return true; 19 | } 20 | 21 | @Override 22 | public boolean useJmx() { 23 | return true; 24 | } 25 | 26 | @Test 27 | public void testMock() throws Exception { 28 | MockEndpoint mock = getMockEndpoint("mock:camel-plantuml-output"); 29 | 30 | 31 | mock.expectedBodiesReceived("@startuml\n" + 32 | "\n" + 33 | "skinparam ArrowColor #Black\n" + 34 | "\n" + 35 | "skinparam rectangle {\n" + 36 | " RoundCorner 20\n" + 37 | "}\n" + 38 | "\n" + 39 | "skinparam rectangle<> {\n" + 40 | " BorderColor #6C8EBF\n" + 41 | " BackgroundColor #DAE8FC\n" + 42 | "}\n" + 43 | "\n" + 44 | "skinparam queue<> {\n" + 45 | "}\n" + 46 | "\n" + 47 | "skinparam queue<> {\n" + 48 | " BorderColor #B85450\n" + 49 | " BackgroundColor #F8CECC\n" + 50 | "}\n" + 51 | "\n" + 52 | "skinparam queue<> {\n" + 53 | " BorderColor #82B366\n" + 54 | " BackgroundColor #D5E8D4\n" + 55 | "}\n" + 56 | "\n" + 57 | "footer Generated with camel-plantuml on %date(\"dd-MM-yyyy HH:mm\")\n" + 58 | "\n" + 59 | "' === Some useful settings for tweaking diagram layout ===\n" + 60 | "'left to right direction\n" + 61 | "'hide stereotype\n" + 62 | "'skinparam nodesep 50\n" + 63 | "'skinparam ranksep 50\n" + 64 | "'skinparam wrapWidth 250\n" + 65 | "\n" + 66 | "rectangle route_5aca19f124057cede73e83f9343843f8 <> as \"\n" + 67 | "pollEnricherHeaderRoute1\n" + 68 | "\"\n" + 69 | "\n" + 70 | "queue endpoint_c1749b7ed34e5395932c33f971ca4151 <><> as \"\n" + 71 | "timer://foo\n" + 72 | "\"\n" + 73 | "\n" + 74 | "endpoint_c1749b7ed34e5395932c33f971ca4151 --> route_5aca19f124057cede73e83f9343843f8 : from\n" + 75 | "\n" + 76 | "@enduml\n"); 77 | 78 | AdviceWith.adviceWith(context, "camel-plantuml-http-trigger", a -> { 79 | a.weaveAddLast().transform(a.body().regexReplaceAll("\r", "")); 80 | a.weaveAddLast().to("mock:camel-plantuml-output"); 81 | } 82 | ); 83 | 84 | context.start(); 85 | 86 | template.sendBody("direct:camel-plantuml-generate-plantuml", null); 87 | MockEndpoint.assertIsSatisfied(context); 88 | } 89 | 90 | @Override 91 | protected RoutesBuilder createRouteBuilder() { 92 | return new RouteBuilder() { 93 | @Override 94 | public void configure() throws Exception { 95 | from(timer("foo").period(5000)).routeId("pollEnricherHeaderRoute1") 96 | .setHeader("dummyHeader", constant("mock://dummyPollEnricher")) 97 | .pollEnrich().header("dummyHeader").id("_pollEnrich01"); 98 | 99 | getContext().addRoutes(new CamelPlantUmlRouteBuilder()); 100 | 101 | } 102 | 103 | }; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/test/java/Enricher/EnricherConstantTest.java: -------------------------------------------------------------------------------- 1 | package Enricher; 2 | 3 | import io.github.ncasaux.camelplantuml.routebuilder.CamelPlantUmlRouteBuilder; 4 | import org.apache.camel.RoutesBuilder; 5 | import org.apache.camel.builder.AdviceWith; 6 | import org.apache.camel.builder.RouteBuilder; 7 | import org.apache.camel.component.mock.MockEndpoint; 8 | import org.apache.camel.test.junit5.CamelTestSupport; 9 | import org.junit.jupiter.api.Test; 10 | 11 | import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.*; 12 | 13 | public class EnricherConstantTest extends CamelTestSupport { 14 | 15 | @Override 16 | public boolean isUseAdviceWith() { 17 | return true; 18 | } 19 | 20 | @Override 21 | public boolean useJmx() { 22 | return true; 23 | } 24 | 25 | @Test 26 | public void testMock() throws Exception { 27 | MockEndpoint mock = getMockEndpoint("mock:camel-plantuml-output"); 28 | 29 | 30 | mock.expectedBodiesReceived("@startuml\n" + 31 | "\n" + 32 | "skinparam ArrowColor #Black\n" + 33 | "\n" + 34 | "skinparam rectangle {\n" + 35 | " RoundCorner 20\n" + 36 | "}\n" + 37 | "\n" + 38 | "skinparam rectangle<> {\n" + 39 | " BorderColor #6C8EBF\n" + 40 | " BackgroundColor #DAE8FC\n" + 41 | "}\n" + 42 | "\n" + 43 | "skinparam queue<> {\n" + 44 | "}\n" + 45 | "\n" + 46 | "skinparam queue<> {\n" + 47 | " BorderColor #B85450\n" + 48 | " BackgroundColor #F8CECC\n" + 49 | "}\n" + 50 | "\n" + 51 | "skinparam queue<> {\n" + 52 | " BorderColor #82B366\n" + 53 | " BackgroundColor #D5E8D4\n" + 54 | "}\n" + 55 | "\n" + 56 | "footer Generated with camel-plantuml on %date(\"dd-MM-yyyy HH:mm\")\n" + 57 | "\n" + 58 | "' === Some useful settings for tweaking diagram layout ===\n" + 59 | "'left to right direction\n" + 60 | "'hide stereotype\n" + 61 | "'skinparam nodesep 50\n" + 62 | "'skinparam ranksep 50\n" + 63 | "'skinparam wrapWidth 250\n" + 64 | "\n" + 65 | "rectangle route_c5804abb0344059454c89ee29ad253f6 <> as \"\n" + 66 | "enricherConstantRoute1\n" + 67 | "\"\n" + 68 | "\n" + 69 | "queue endpoint_104c72c86213ec224b859d0b496d53a6 <><> as \"\n" + 70 | "mock://dummyEnricher\n" + 71 | "\"\n" + 72 | "\n" + 73 | "queue endpoint_c1749b7ed34e5395932c33f971ca4151 <><> as \"\n" + 74 | "timer://foo\n" + 75 | "\"\n" + 76 | "\n" + 77 | "endpoint_c1749b7ed34e5395932c33f971ca4151 --> route_c5804abb0344059454c89ee29ad253f6 : from\n" + 78 | "\n" + 79 | "route_c5804abb0344059454c89ee29ad253f6 --> endpoint_104c72c86213ec224b859d0b496d53a6 : enrich\n" + 80 | "\n" + 81 | "@enduml\n"); 82 | 83 | AdviceWith.adviceWith(context, "camel-plantuml-http-trigger", a -> { 84 | a.weaveAddLast().transform(a.body().regexReplaceAll("\r", "")); 85 | a.weaveAddLast().to("mock:camel-plantuml-output"); 86 | } 87 | ); 88 | 89 | context.start(); 90 | 91 | template.sendBody("direct:camel-plantuml-generate-plantuml", null); 92 | MockEndpoint.assertIsSatisfied(context); 93 | } 94 | 95 | @Override 96 | protected RoutesBuilder createRouteBuilder() { 97 | return new RouteBuilder() { 98 | @Override 99 | public void configure() throws Exception { 100 | from(timer("foo").period(5000)).routeId("enricherConstantRoute1") 101 | .enrich().constant("mock://dummyEnricher").id("_enrich01"); 102 | 103 | getContext().addRoutes(new CamelPlantUmlRouteBuilder()); 104 | 105 | } 106 | 107 | }; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/test/java/PollEnricher/PollEnricherConstantTest.java: -------------------------------------------------------------------------------- 1 | package PollEnricher; 2 | 3 | import io.github.ncasaux.camelplantuml.routebuilder.CamelPlantUmlRouteBuilder; 4 | import org.apache.camel.RoutesBuilder; 5 | import org.apache.camel.builder.AdviceWith; 6 | import org.apache.camel.builder.RouteBuilder; 7 | import org.apache.camel.component.mock.MockEndpoint; 8 | import org.apache.camel.test.junit5.CamelTestSupport; 9 | import org.junit.jupiter.api.Test; 10 | 11 | import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.*; 12 | 13 | public class PollEnricherConstantTest extends CamelTestSupport { 14 | 15 | @Override 16 | public boolean isUseAdviceWith() { 17 | return true; 18 | } 19 | 20 | @Override 21 | public boolean useJmx() { 22 | return true; 23 | } 24 | 25 | @Test 26 | public void testMock() throws Exception { 27 | MockEndpoint mock = getMockEndpoint("mock:camel-plantuml-output"); 28 | 29 | 30 | mock.expectedBodiesReceived("@startuml\n" + 31 | "\n" + 32 | "skinparam ArrowColor #Black\n" + 33 | "\n" + 34 | "skinparam rectangle {\n" + 35 | " RoundCorner 20\n" + 36 | "}\n" + 37 | "\n" + 38 | "skinparam rectangle<> {\n" + 39 | " BorderColor #6C8EBF\n" + 40 | " BackgroundColor #DAE8FC\n" + 41 | "}\n" + 42 | "\n" + 43 | "skinparam queue<> {\n" + 44 | "}\n" + 45 | "\n" + 46 | "skinparam queue<> {\n" + 47 | " BorderColor #B85450\n" + 48 | " BackgroundColor #F8CECC\n" + 49 | "}\n" + 50 | "\n" + 51 | "skinparam queue<> {\n" + 52 | " BorderColor #82B366\n" + 53 | " BackgroundColor #D5E8D4\n" + 54 | "}\n" + 55 | "\n" + 56 | "footer Generated with camel-plantuml on %date(\"dd-MM-yyyy HH:mm\")\n" + 57 | "\n" + 58 | "' === Some useful settings for tweaking diagram layout ===\n" + 59 | "'left to right direction\n" + 60 | "'hide stereotype\n" + 61 | "'skinparam nodesep 50\n" + 62 | "'skinparam ranksep 50\n" + 63 | "'skinparam wrapWidth 250\n" + 64 | "\n" + 65 | "rectangle route_ca4a304cb67c2463d0e5ade782c39310 <> as \"\n" + 66 | "pollEnricherConstantRoute1\n" + 67 | "\"\n" + 68 | "\n" + 69 | "queue endpoint_c1749b7ed34e5395932c33f971ca4151 <><> as \"\n" + 70 | "timer://foo\n" + 71 | "\"\n" + 72 | "\n" + 73 | "queue endpoint_3bdf0a6c6729de9884a3e227b55e79f9 <><> as \"\n" + 74 | "mock://dummyPollEnricher\n" + 75 | "\"\n" + 76 | "\n" + 77 | "endpoint_c1749b7ed34e5395932c33f971ca4151 --> route_ca4a304cb67c2463d0e5ade782c39310 : from\n" + 78 | "\n" + 79 | "endpoint_3bdf0a6c6729de9884a3e227b55e79f9 --> route_ca4a304cb67c2463d0e5ade782c39310 : pollEnrich\n" + 80 | "\n" + 81 | "@enduml\n"); 82 | 83 | AdviceWith.adviceWith(context, "camel-plantuml-http-trigger", a -> { 84 | a.weaveAddLast().transform(a.body().regexReplaceAll("\r", "")); 85 | a.weaveAddLast().to("mock:camel-plantuml-output"); 86 | } 87 | ); 88 | 89 | context.start(); 90 | 91 | template.sendBody("direct:camel-plantuml-generate-plantuml", null); 92 | MockEndpoint.assertIsSatisfied(context); 93 | } 94 | 95 | @Override 96 | protected RoutesBuilder createRouteBuilder() { 97 | return new RouteBuilder() { 98 | @Override 99 | public void configure() throws Exception { 100 | from(timer("foo").period(5000)).routeId("pollEnricherConstantRoute1") 101 | .pollEnrich().constant("mock://dummyPollEnricher").id("_pollEnrich01"); 102 | 103 | getContext().addRoutes(new CamelPlantUmlRouteBuilder()); 104 | 105 | } 106 | 107 | }; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/test/java/WireTap/WireTapStaticTest.java: -------------------------------------------------------------------------------- 1 | package WireTap; 2 | 3 | import io.github.ncasaux.camelplantuml.routebuilder.CamelPlantUmlRouteBuilder; 4 | import org.apache.camel.RoutesBuilder; 5 | import org.apache.camel.builder.AdviceWith; 6 | import org.apache.camel.builder.RouteBuilder; 7 | import org.apache.camel.component.mock.MockEndpoint; 8 | import org.apache.camel.test.junit5.CamelTestSupport; 9 | import org.junit.jupiter.api.Test; 10 | 11 | import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.*; 12 | 13 | public class WireTapStaticTest extends CamelTestSupport { 14 | 15 | @Override 16 | public boolean isUseAdviceWith() { 17 | return true; 18 | } 19 | 20 | @Override 21 | public boolean useJmx() { 22 | return true; 23 | } 24 | 25 | @Test 26 | public void testMock() throws Exception { 27 | MockEndpoint mock = getMockEndpoint("mock:camel-plantuml-output"); 28 | 29 | 30 | mock.expectedBodiesReceived("@startuml\n" + 31 | "\n" + 32 | "skinparam ArrowColor #Black\n" + 33 | "\n" + 34 | "skinparam rectangle {\n" + 35 | " RoundCorner 20\n" + 36 | "}\n" + 37 | "\n" + 38 | "skinparam rectangle<> {\n" + 39 | " BorderColor #6C8EBF\n" + 40 | " BackgroundColor #DAE8FC\n" + 41 | "}\n" + 42 | "\n" + 43 | "skinparam queue<> {\n" + 44 | "}\n" + 45 | "\n" + 46 | "skinparam queue<> {\n" + 47 | " BorderColor #B85450\n" + 48 | " BackgroundColor #F8CECC\n" + 49 | "}\n" + 50 | "\n" + 51 | "skinparam queue<> {\n" + 52 | " BorderColor #82B366\n" + 53 | " BackgroundColor #D5E8D4\n" + 54 | "}\n" + 55 | "\n" + 56 | "footer Generated with camel-plantuml on %date(\"dd-MM-yyyy HH:mm\")\n" + 57 | "\n" + 58 | "' === Some useful settings for tweaking diagram layout ===\n" + 59 | "'left to right direction\n" + 60 | "'hide stereotype\n" + 61 | "'skinparam nodesep 50\n" + 62 | "'skinparam ranksep 50\n" + 63 | "'skinparam wrapWidth 250\n" + 64 | "\n" + 65 | "rectangle route_1d0615e27dff16390ab2050dbb552ffc <> as \"\n" + 66 | "wireTapStaticRoute1\n" + 67 | "\"\n" + 68 | "\n" + 69 | "queue endpoint_c1749b7ed34e5395932c33f971ca4151 <><> as \"\n" + 70 | "timer://foo\n" + 71 | "\"\n" + 72 | "\n" + 73 | "queue endpoint_c311d731f05326f646d65811b0bd8cd8 <><> as \"\n" + 74 | "mock://dummyStaticWireTap\n" + 75 | "\"\n" + 76 | "\n" + 77 | "endpoint_c1749b7ed34e5395932c33f971ca4151 --> route_1d0615e27dff16390ab2050dbb552ffc : from\n" + 78 | "\n" + 79 | "route_1d0615e27dff16390ab2050dbb552ffc --> endpoint_c311d731f05326f646d65811b0bd8cd8 : wiretap\n" + 80 | "\n" + 81 | "@enduml\n"); 82 | 83 | AdviceWith.adviceWith(context, "camel-plantuml-http-trigger", a -> { 84 | a.weaveAddLast().transform(a.body().regexReplaceAll("\r", "")); 85 | a.weaveAddLast().to("mock:camel-plantuml-output"); 86 | } 87 | ); 88 | 89 | context.start(); 90 | 91 | template.sendBody("direct:camel-plantuml-generate-plantuml", null); 92 | MockEndpoint.assertIsSatisfied(context); 93 | } 94 | 95 | @Override 96 | protected RoutesBuilder createRouteBuilder() { 97 | return new RouteBuilder() { 98 | @Override 99 | public void configure() throws Exception { 100 | from(timer("foo").period(5000)).routeId("wireTapStaticRoute1") 101 | .wireTap("mock://dummyStaticWireTap").dynamicUri(false).id("_wireTap01") 102 | .end(); 103 | 104 | getContext().addRoutes(new CamelPlantUmlRouteBuilder()); 105 | 106 | } 107 | 108 | }; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/test/java/RecipientList/RecipientListConstantTest.java: -------------------------------------------------------------------------------- 1 | package RecipientList; 2 | 3 | import io.github.ncasaux.camelplantuml.routebuilder.CamelPlantUmlRouteBuilder; 4 | import org.apache.camel.RoutesBuilder; 5 | import org.apache.camel.builder.AdviceWith; 6 | import org.apache.camel.builder.RouteBuilder; 7 | import org.apache.camel.component.mock.MockEndpoint; 8 | import org.apache.camel.test.junit5.CamelTestSupport; 9 | import org.junit.jupiter.api.Test; 10 | 11 | import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.*; 12 | 13 | public class RecipientListConstantTest extends CamelTestSupport { 14 | 15 | @Override 16 | public boolean isUseAdviceWith() { 17 | return true; 18 | } 19 | 20 | @Override 21 | public boolean useJmx() { 22 | return true; 23 | } 24 | 25 | @Test 26 | public void testMock() throws Exception { 27 | MockEndpoint mock = getMockEndpoint("mock:camel-plantuml-output"); 28 | 29 | 30 | mock.expectedBodiesReceived("@startuml\n" + 31 | "\n" + 32 | "skinparam ArrowColor #Black\n" + 33 | "\n" + 34 | "skinparam rectangle {\n" + 35 | " RoundCorner 20\n" + 36 | "}\n" + 37 | "\n" + 38 | "skinparam rectangle<> {\n" + 39 | " BorderColor #6C8EBF\n" + 40 | " BackgroundColor #DAE8FC\n" + 41 | "}\n" + 42 | "\n" + 43 | "skinparam queue<> {\n" + 44 | "}\n" + 45 | "\n" + 46 | "skinparam queue<> {\n" + 47 | " BorderColor #B85450\n" + 48 | " BackgroundColor #F8CECC\n" + 49 | "}\n" + 50 | "\n" + 51 | "skinparam queue<> {\n" + 52 | " BorderColor #82B366\n" + 53 | " BackgroundColor #D5E8D4\n" + 54 | "}\n" + 55 | "\n" + 56 | "footer Generated with camel-plantuml on %date(\"dd-MM-yyyy HH:mm\")\n" + 57 | "\n" + 58 | "' === Some useful settings for tweaking diagram layout ===\n" + 59 | "'left to right direction\n" + 60 | "'hide stereotype\n" + 61 | "'skinparam nodesep 50\n" + 62 | "'skinparam ranksep 50\n" + 63 | "'skinparam wrapWidth 250\n" + 64 | "\n" + 65 | "rectangle route_2122eec0d84dc733bee3b31b00081b9c <> as \"\n" + 66 | "recipientListConstantRoute1\n" + 67 | "\"\n" + 68 | "\n" + 69 | "queue endpoint_c1749b7ed34e5395932c33f971ca4151 <><> as \"\n" + 70 | "timer://foo\n" + 71 | "\"\n" + 72 | "\n" + 73 | "queue endpoint_13af2a5b579b607346fe28664f43b6c5 <><> as \"\n" + 74 | "mock://dummyRecipient\n" + 75 | "\"\n" + 76 | "\n" + 77 | "endpoint_c1749b7ed34e5395932c33f971ca4151 --> route_2122eec0d84dc733bee3b31b00081b9c : from\n" + 78 | "\n" + 79 | "route_2122eec0d84dc733bee3b31b00081b9c --> endpoint_13af2a5b579b607346fe28664f43b6c5 : recipientList\n" + 80 | "\n" + 81 | "@enduml\n"); 82 | 83 | AdviceWith.adviceWith(context, "camel-plantuml-http-trigger", a -> { 84 | a.weaveAddLast().transform(a.body().regexReplaceAll("\r", "")); 85 | a.weaveAddLast().to("mock:camel-plantuml-output"); 86 | } 87 | ); 88 | 89 | context.start(); 90 | 91 | template.sendBody("direct:camel-plantuml-generate-plantuml", null); 92 | MockEndpoint.assertIsSatisfied(context); 93 | } 94 | 95 | @Override 96 | protected RoutesBuilder createRouteBuilder() { 97 | return new RouteBuilder() { 98 | @Override 99 | public void configure() throws Exception { 100 | from(timer("foo").period(5000)).routeId("recipientListConstantRoute1") 101 | .recipientList().constant("mock://dummyRecipient").id("_recipientList01"); 102 | 103 | getContext().addRoutes(new CamelPlantUmlRouteBuilder()); 104 | 105 | } 106 | 107 | }; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/test/java/WireTap/WireTapDynamicTest.java: -------------------------------------------------------------------------------- 1 | package WireTap; 2 | 3 | import io.github.ncasaux.camelplantuml.routebuilder.CamelPlantUmlRouteBuilder; 4 | import org.apache.camel.RoutesBuilder; 5 | import org.apache.camel.builder.AdviceWith; 6 | import org.apache.camel.builder.RouteBuilder; 7 | import org.apache.camel.component.mock.MockEndpoint; 8 | import org.apache.camel.test.junit5.CamelTestSupport; 9 | import org.junit.jupiter.api.Test; 10 | 11 | import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.timer; 12 | 13 | public class WireTapDynamicTest extends CamelTestSupport { 14 | 15 | @Override 16 | public boolean isUseAdviceWith() { 17 | return true; 18 | } 19 | 20 | @Override 21 | public boolean useJmx() { 22 | return true; 23 | } 24 | 25 | @Test 26 | public void testMock() throws Exception { 27 | MockEndpoint mock = getMockEndpoint("mock:camel-plantuml-output"); 28 | 29 | 30 | mock.expectedBodiesReceived("@startuml\n" + 31 | "\n" + 32 | "skinparam ArrowColor #Black\n" + 33 | "\n" + 34 | "skinparam rectangle {\n" + 35 | " RoundCorner 20\n" + 36 | "}\n" + 37 | "\n" + 38 | "skinparam rectangle<> {\n" + 39 | " BorderColor #6C8EBF\n" + 40 | " BackgroundColor #DAE8FC\n" + 41 | "}\n" + 42 | "\n" + 43 | "skinparam queue<> {\n" + 44 | "}\n" + 45 | "\n" + 46 | "skinparam queue<> {\n" + 47 | " BorderColor #B85450\n" + 48 | " BackgroundColor #F8CECC\n" + 49 | "}\n" + 50 | "\n" + 51 | "skinparam queue<> {\n" + 52 | " BorderColor #82B366\n" + 53 | " BackgroundColor #D5E8D4\n" + 54 | "}\n" + 55 | "\n" + 56 | "footer Generated with camel-plantuml on %date(\"dd-MM-yyyy HH:mm\")\n" + 57 | "\n" + 58 | "' === Some useful settings for tweaking diagram layout ===\n" + 59 | "'left to right direction\n" + 60 | "'hide stereotype\n" + 61 | "'skinparam nodesep 50\n" + 62 | "'skinparam ranksep 50\n" + 63 | "'skinparam wrapWidth 250\n" + 64 | "\n" + 65 | "rectangle route_1d0615e27dff16390ab2050dbb552ffc <> as \"\n" + 66 | "wireTapStaticRoute1\n" + 67 | "\"\n" + 68 | "\n" + 69 | "queue endpoint_c1749b7ed34e5395932c33f971ca4151 <><> as \"\n" + 70 | "timer://foo\n" + 71 | "\"\n" + 72 | "\n" + 73 | "endpoint_c1749b7ed34e5395932c33f971ca4151 --> route_1d0615e27dff16390ab2050dbb552ffc : from\n" + 74 | "\n" + 75 | "queue dynamic_producer_endpoint_47b1af78d16f3d758a742cc808e97727 <><> as \"\n" + 76 | "mock://dummyDynamicWireTap\n" + 77 | "\"\n" + 78 | "\n" + 79 | "route_1d0615e27dff16390ab2050dbb552ffc --> dynamic_producer_endpoint_47b1af78d16f3d758a742cc808e97727 : wiretap\n" + 80 | "\n" + 81 | "@enduml\n"); 82 | 83 | AdviceWith.adviceWith(context, "camel-plantuml-http-trigger", a -> { 84 | a.weaveAddLast().transform(a.body().regexReplaceAll("\r", "")); 85 | a.weaveAddLast().to("mock:camel-plantuml-output"); 86 | } 87 | ); 88 | 89 | context.start(); 90 | 91 | template.sendBody("direct:camel-plantuml-generate-plantuml", null); 92 | MockEndpoint.assertIsSatisfied(context); 93 | } 94 | 95 | @Override 96 | protected RoutesBuilder createRouteBuilder() { 97 | return new RouteBuilder() { 98 | @Override 99 | public void configure() throws Exception { 100 | from(timer("foo").period(5000)).routeId("wireTapStaticRoute1") 101 | .wireTap("mock://dummyDynamicWireTap").id("_wireTap01") 102 | .end(); 103 | 104 | getContext().addRoutes(new CamelPlantUmlRouteBuilder()); 105 | 106 | } 107 | 108 | }; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/test/java/Enricher/EnricherSimpleTest.java: -------------------------------------------------------------------------------- 1 | package Enricher; 2 | 3 | import io.github.ncasaux.camelplantuml.routebuilder.CamelPlantUmlRouteBuilder; 4 | import org.apache.camel.RoutesBuilder; 5 | import org.apache.camel.builder.AdviceWith; 6 | import org.apache.camel.builder.RouteBuilder; 7 | import org.apache.camel.component.mock.MockEndpoint; 8 | import org.apache.camel.test.junit5.CamelTestSupport; 9 | import org.junit.jupiter.api.Test; 10 | 11 | import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.*; 12 | 13 | public class EnricherSimpleTest extends CamelTestSupport { 14 | 15 | @Override 16 | public boolean isUseAdviceWith() { 17 | return true; 18 | } 19 | 20 | @Override 21 | public boolean useJmx() { 22 | return true; 23 | } 24 | 25 | @Test 26 | public void testMock() throws Exception { 27 | MockEndpoint mock = getMockEndpoint("mock:camel-plantuml-output"); 28 | 29 | 30 | mock.expectedBodiesReceived("@startuml\n" + 31 | "\n" + 32 | "skinparam ArrowColor #Black\n" + 33 | "\n" + 34 | "skinparam rectangle {\n" + 35 | " RoundCorner 20\n" + 36 | "}\n" + 37 | "\n" + 38 | "skinparam rectangle<> {\n" + 39 | " BorderColor #6C8EBF\n" + 40 | " BackgroundColor #DAE8FC\n" + 41 | "}\n" + 42 | "\n" + 43 | "skinparam queue<> {\n" + 44 | "}\n" + 45 | "\n" + 46 | "skinparam queue<> {\n" + 47 | " BorderColor #B85450\n" + 48 | " BackgroundColor #F8CECC\n" + 49 | "}\n" + 50 | "\n" + 51 | "skinparam queue<> {\n" + 52 | " BorderColor #82B366\n" + 53 | " BackgroundColor #D5E8D4\n" + 54 | "}\n" + 55 | "\n" + 56 | "footer Generated with camel-plantuml on %date(\"dd-MM-yyyy HH:mm\")\n" + 57 | "\n" + 58 | "' === Some useful settings for tweaking diagram layout ===\n" + 59 | "'left to right direction\n" + 60 | "'hide stereotype\n" + 61 | "'skinparam nodesep 50\n" + 62 | "'skinparam ranksep 50\n" + 63 | "'skinparam wrapWidth 250\n" + 64 | "\n" + 65 | "rectangle route_12a31fc3d5ef8c65a9f540f965f208f1 <> as \"\n" + 66 | "enricherSimpleRoute1\n" + 67 | "\"\n" + 68 | "\n" + 69 | "queue endpoint_c1749b7ed34e5395932c33f971ca4151 <><> as \"\n" + 70 | "timer://foo\n" + 71 | "\"\n" + 72 | "\n" + 73 | "endpoint_c1749b7ed34e5395932c33f971ca4151 --> route_12a31fc3d5ef8c65a9f540f965f208f1 : from\n" + 74 | "\n" + 75 | "queue dynamic_producer_endpoint_1d05506f63ef7fbf0e469f9408779127 <><> as \"\n" + 76 | "mock://dummyEnricher-${body}\n" + 77 | "\"\n" + 78 | "\n" + 79 | "route_12a31fc3d5ef8c65a9f540f965f208f1 --> dynamic_producer_endpoint_1d05506f63ef7fbf0e469f9408779127 : enrich\n" + 80 | "\n" + 81 | "@enduml\n"); 82 | 83 | AdviceWith.adviceWith(context, "camel-plantuml-http-trigger", a -> { 84 | a.weaveAddLast().transform(a.body().regexReplaceAll("\r", "")); 85 | a.weaveAddLast().to("mock:camel-plantuml-output"); 86 | } 87 | ); 88 | 89 | context.start(); 90 | 91 | template.sendBody("direct:camel-plantuml-generate-plantuml", null); 92 | MockEndpoint.assertIsSatisfied(context); 93 | } 94 | 95 | @Override 96 | protected RoutesBuilder createRouteBuilder() { 97 | return new RouteBuilder() { 98 | @Override 99 | public void configure() throws Exception { 100 | from(timer("foo").period(5000)).routeId("enricherSimpleRoute1") 101 | .setBody(constant("bar")) 102 | .enrich().simple("mock://dummyEnricher-${body}").id("_enrich01"); 103 | 104 | getContext().addRoutes(new CamelPlantUmlRouteBuilder()); 105 | 106 | } 107 | 108 | }; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/test/java/RecipientList/RecipientListSimpleTest.java: -------------------------------------------------------------------------------- 1 | package RecipientList; 2 | 3 | import io.github.ncasaux.camelplantuml.routebuilder.CamelPlantUmlRouteBuilder; 4 | import org.apache.camel.RoutesBuilder; 5 | import org.apache.camel.builder.AdviceWith; 6 | import org.apache.camel.builder.RouteBuilder; 7 | import org.apache.camel.component.mock.MockEndpoint; 8 | import org.apache.camel.test.junit5.CamelTestSupport; 9 | import org.junit.jupiter.api.Test; 10 | 11 | import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.timer; 12 | 13 | public class RecipientListSimpleTest extends CamelTestSupport { 14 | 15 | @Override 16 | public boolean isUseAdviceWith() { 17 | return true; 18 | } 19 | 20 | @Override 21 | public boolean useJmx() { 22 | return true; 23 | } 24 | 25 | @Test 26 | public void testMock() throws Exception { 27 | MockEndpoint mock = getMockEndpoint("mock:camel-plantuml-output"); 28 | 29 | 30 | mock.expectedBodiesReceived("@startuml\n" + 31 | "\n" + 32 | "skinparam ArrowColor #Black\n" + 33 | "\n" + 34 | "skinparam rectangle {\n" + 35 | " RoundCorner 20\n" + 36 | "}\n" + 37 | "\n" + 38 | "skinparam rectangle<> {\n" + 39 | " BorderColor #6C8EBF\n" + 40 | " BackgroundColor #DAE8FC\n" + 41 | "}\n" + 42 | "\n" + 43 | "skinparam queue<> {\n" + 44 | "}\n" + 45 | "\n" + 46 | "skinparam queue<> {\n" + 47 | " BorderColor #B85450\n" + 48 | " BackgroundColor #F8CECC\n" + 49 | "}\n" + 50 | "\n" + 51 | "skinparam queue<> {\n" + 52 | " BorderColor #82B366\n" + 53 | " BackgroundColor #D5E8D4\n" + 54 | "}\n" + 55 | "\n" + 56 | "footer Generated with camel-plantuml on %date(\"dd-MM-yyyy HH:mm\")\n" + 57 | "\n" + 58 | "' === Some useful settings for tweaking diagram layout ===\n" + 59 | "'left to right direction\n" + 60 | "'hide stereotype\n" + 61 | "'skinparam nodesep 50\n" + 62 | "'skinparam ranksep 50\n" + 63 | "'skinparam wrapWidth 250\n" + 64 | "\n" + 65 | "rectangle route_62fbcd625ec544f809248b42b7069ef6 <> as \"\n" + 66 | "recipientListSimpleRoute1\n" + 67 | "\"\n" + 68 | "\n" + 69 | "queue endpoint_c1749b7ed34e5395932c33f971ca4151 <><> as \"\n" + 70 | "timer://foo\n" + 71 | "\"\n" + 72 | "\n" + 73 | "endpoint_c1749b7ed34e5395932c33f971ca4151 --> route_62fbcd625ec544f809248b42b7069ef6 : from\n" + 74 | "\n" + 75 | "queue dynamic_producer_endpoint_733ba1f07cf27f4e3ce3da43b65eaf79 <><> as \"\n" + 76 | "ock://dummyRecipient-${body}\n" + 77 | "\"\n" + 78 | "\n" + 79 | "route_62fbcd625ec544f809248b42b7069ef6 --> dynamic_producer_endpoint_733ba1f07cf27f4e3ce3da43b65eaf79 : recipientList\n" + 80 | "\n" + 81 | "@enduml\n"); 82 | 83 | AdviceWith.adviceWith(context, "camel-plantuml-http-trigger", a -> { 84 | a.weaveAddLast().transform(a.body().regexReplaceAll("\r", "")); 85 | a.weaveAddLast().to("mock:camel-plantuml-output"); 86 | } 87 | ); 88 | 89 | context.start(); 90 | 91 | template.sendBody("direct:camel-plantuml-generate-plantuml", null); 92 | MockEndpoint.assertIsSatisfied(context); 93 | } 94 | 95 | @Override 96 | protected RoutesBuilder createRouteBuilder() { 97 | return new RouteBuilder() { 98 | @Override 99 | public void configure() throws Exception { 100 | from(timer("foo").period(5000)).routeId("recipientListSimpleRoute1") 101 | .setBody(constant("bar")) 102 | .recipientList().simple("ock://dummyRecipient-${body}").id("_recipientList01"); 103 | 104 | getContext().addRoutes(new CamelPlantUmlRouteBuilder()); 105 | 106 | } 107 | 108 | }; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/test/java/PollEnricher/PollEnricherSimpleTest.java: -------------------------------------------------------------------------------- 1 | package PollEnricher; 2 | 3 | import io.github.ncasaux.camelplantuml.routebuilder.CamelPlantUmlRouteBuilder; 4 | import org.apache.camel.RoutesBuilder; 5 | import org.apache.camel.builder.AdviceWith; 6 | import org.apache.camel.builder.RouteBuilder; 7 | import org.apache.camel.component.mock.MockEndpoint; 8 | import org.apache.camel.test.junit5.CamelTestSupport; 9 | import org.junit.jupiter.api.Test; 10 | 11 | import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.mock; 12 | import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.timer; 13 | 14 | public class PollEnricherSimpleTest extends CamelTestSupport { 15 | 16 | @Override 17 | public boolean isUseAdviceWith() { 18 | return true; 19 | } 20 | 21 | @Override 22 | public boolean useJmx() { 23 | return true; 24 | } 25 | 26 | @Test 27 | public void testMock() throws Exception { 28 | MockEndpoint mock = getMockEndpoint("mock:camel-plantuml-output"); 29 | 30 | 31 | mock.expectedBodiesReceived("@startuml\n" + 32 | "\n" + 33 | "skinparam ArrowColor #Black\n" + 34 | "\n" + 35 | "skinparam rectangle {\n" + 36 | " RoundCorner 20\n" + 37 | "}\n" + 38 | "\n" + 39 | "skinparam rectangle<> {\n" + 40 | " BorderColor #6C8EBF\n" + 41 | " BackgroundColor #DAE8FC\n" + 42 | "}\n" + 43 | "\n" + 44 | "skinparam queue<> {\n" + 45 | "}\n" + 46 | "\n" + 47 | "skinparam queue<> {\n" + 48 | " BorderColor #B85450\n" + 49 | " BackgroundColor #F8CECC\n" + 50 | "}\n" + 51 | "\n" + 52 | "skinparam queue<> {\n" + 53 | " BorderColor #82B366\n" + 54 | " BackgroundColor #D5E8D4\n" + 55 | "}\n" + 56 | "\n" + 57 | "footer Generated with camel-plantuml on %date(\"dd-MM-yyyy HH:mm\")\n" + 58 | "\n" + 59 | "' === Some useful settings for tweaking diagram layout ===\n" + 60 | "'left to right direction\n" + 61 | "'hide stereotype\n" + 62 | "'skinparam nodesep 50\n" + 63 | "'skinparam ranksep 50\n" + 64 | "'skinparam wrapWidth 250\n" + 65 | "\n" + 66 | "rectangle route_135e5ff0e32ab17dd81d220783879319 <> as \"\n" + 67 | "pollEnricherSimpleRoute1\n" + 68 | "\"\n" + 69 | "\n" + 70 | "queue endpoint_c1749b7ed34e5395932c33f971ca4151 <><> as \"\n" + 71 | "timer://foo\n" + 72 | "\"\n" + 73 | "\n" + 74 | "endpoint_c1749b7ed34e5395932c33f971ca4151 --> route_135e5ff0e32ab17dd81d220783879319 : from\n" + 75 | "\n" + 76 | "queue dynamic_consumer_endpoint_7c1c13020cdf66a9db5c822a4b97e81d <><> as \"\n" + 77 | "mock://dummyPollEnricher-${body}\n" + 78 | "\"\n" + 79 | "\n" + 80 | "dynamic_consumer_endpoint_7c1c13020cdf66a9db5c822a4b97e81d --> route_135e5ff0e32ab17dd81d220783879319 : pollEnrich\n" + 81 | "\n" + 82 | "@enduml\n"); 83 | 84 | AdviceWith.adviceWith(context, "camel-plantuml-http-trigger", a -> { 85 | a.weaveAddLast().transform(a.body().regexReplaceAll("\r", "")); 86 | a.weaveAddLast().to("mock:camel-plantuml-output"); 87 | } 88 | ); 89 | 90 | context.start(); 91 | 92 | template.sendBody("direct:camel-plantuml-generate-plantuml", null); 93 | MockEndpoint.assertIsSatisfied(context); 94 | } 95 | 96 | @Override 97 | protected RoutesBuilder createRouteBuilder() { 98 | return new RouteBuilder() { 99 | @Override 100 | public void configure() throws Exception { 101 | from(timer("foo").period(5000)).routeId("pollEnricherSimpleRoute1") 102 | .setBody(constant("bar")) 103 | .pollEnrich().simple("mock://dummyPollEnricher-${body}").id("_pollEnrich01"); 104 | 105 | getContext().addRoutes(new CamelPlantUmlRouteBuilder()); 106 | 107 | } 108 | 109 | }; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/java/io/github/ncasaux/camelplantuml/processor/GetRoutesInfoProcessor.java: -------------------------------------------------------------------------------- 1 | package io.github.ncasaux.camelplantuml.processor; 2 | 3 | import io.github.ncasaux.camelplantuml.extractor.RoutesInfoExtractor; 4 | import io.github.ncasaux.camelplantuml.extractor.processor.*; 5 | import io.github.ncasaux.camelplantuml.generator.*; 6 | import io.github.ncasaux.camelplantuml.model.ConsumerInfo; 7 | import io.github.ncasaux.camelplantuml.model.EndpointBaseUriInfo; 8 | import io.github.ncasaux.camelplantuml.model.ProducerInfo; 9 | import io.github.ncasaux.camelplantuml.model.RouteInfo; 10 | import io.github.ncasaux.camelplantuml.model.query.Parameters; 11 | import io.github.ncasaux.camelplantuml.utils.JmxUtils; 12 | import org.apache.camel.Exchange; 13 | import org.apache.camel.Processor; 14 | import org.slf4j.Logger; 15 | import org.slf4j.LoggerFactory; 16 | 17 | import javax.management.MBeanServerConnection; 18 | import javax.management.remote.JMXConnector; 19 | import java.util.ArrayList; 20 | import java.util.HashMap; 21 | 22 | public class GetRoutesInfoProcessor implements Processor { 23 | 24 | private static final Logger LOGGER = LoggerFactory.getLogger(GetRoutesInfoProcessor.class); 25 | 26 | public final static String[] routeIdFilters = {".*camel-plantuml.*"}; 27 | public final static String[] endpointBaseUriFilters = {".*camel-plantuml.*"}; 28 | public final static String[] camelInternalEndpointSchemeFilters = {"direct","seda"}; 29 | private final String jmxHost = System.getProperty("jmxHost"); 30 | 31 | @Override 32 | public void process(Exchange exchange) throws Exception { 33 | 34 | Parameters parameters = new Parameters( 35 | Boolean.parseBoolean(exchange.getIn().getHeader("connectRoutes", String.class)), 36 | exchange.getIn().getHeader("uriFilterPattern", String.class)); 37 | 38 | HashMap routesInfo = new HashMap<>(); //Hashmap key will be the routeId of the Camel route 39 | ArrayList consumersInfo = new ArrayList<>(); 40 | ArrayList producersInfo = new ArrayList<>(); 41 | HashMap endpointBaseUrisInfo = new HashMap<>(); //Hashmap key will be the endpoint base URI of the endpoint 42 | 43 | MBeanServerConnection mbeanServer; 44 | 45 | if (jmxHost == null) { 46 | LOGGER.info("Getting MBean server"); 47 | mbeanServer = exchange.getContext().getManagementStrategy().getManagementAgent().getMBeanServer(); 48 | } else { 49 | LOGGER.info("Getting MBean server from provided jmxHost \"".concat(jmxHost).concat("\"")); 50 | JMXConnector connector = JmxUtils.getConnector(jmxHost); 51 | mbeanServer = connector.getMBeanServerConnection(); 52 | } 53 | 54 | LOGGER.info("Processing routes"); 55 | RoutesInfoExtractor.getRoutesInfo(mbeanServer, routesInfo, consumersInfo, endpointBaseUrisInfo); 56 | 57 | LOGGER.info("Processing SendProcessor processors"); 58 | SendProcessorInfoExtractor.getProcessorsInfo(mbeanServer, producersInfo, endpointBaseUrisInfo); 59 | 60 | LOGGER.info("Processing SendDynamicProcessor processors"); 61 | SendDynamicProcessorInfoExtractor.getProcessorsInfo(mbeanServer, producersInfo); 62 | 63 | LOGGER.info("Processing Enricher processors"); 64 | EnricherInfoExtractor.getProcessorsInfo(mbeanServer, producersInfo, endpointBaseUrisInfo); 65 | 66 | LOGGER.info("Processing PollEnricher processors"); 67 | PollEnricherInfoExtractor.getProcessorsInfo(mbeanServer, consumersInfo, endpointBaseUrisInfo); 68 | 69 | LOGGER.info("Processing WireTapProcessor processors"); 70 | WireTapProcessorInfoExtractor.getProcessorsInfo(mbeanServer, producersInfo, endpointBaseUrisInfo); 71 | 72 | LOGGER.info("Processing RecipientList processors"); 73 | RecipientListInfoExtractor.getProcessorsInfo(mbeanServer, producersInfo, endpointBaseUrisInfo); 74 | 75 | LOGGER.info("Generating PlantUML diagram"); 76 | String umlString = HeaderDiagramGenerator.generateUmlString(exchange.getContext().getName()) 77 | .concat(RoutesDiagramGenerator.generateUmlString(routesInfo, parameters)) 78 | .concat(EndpointsDiagramGenerator.generateUmlString(consumersInfo, producersInfo, endpointBaseUrisInfo, parameters)) 79 | .concat(ConsumersDiagramGenerator.generateUmlString(consumersInfo, producersInfo, endpointBaseUrisInfo, routesInfo, parameters)) 80 | .concat(ProducersDiagramGenerator.generateUmlString(consumersInfo, producersInfo, endpointBaseUrisInfo, routesInfo, parameters)) 81 | .concat(FooterDiagramGenerator.generateUmlString()); 82 | 83 | exchange.getIn().setHeader("content-type", "text/plain;charset=utf-8"); 84 | exchange.getIn().setBody(umlString); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/java/io/github/ncasaux/camelplantuml/generator/ConsumersDiagramGenerator.java: -------------------------------------------------------------------------------- 1 | package io.github.ncasaux.camelplantuml.generator; 2 | 3 | import io.github.ncasaux.camelplantuml.model.ConsumerInfo; 4 | import io.github.ncasaux.camelplantuml.model.EndpointBaseUriInfo; 5 | import io.github.ncasaux.camelplantuml.model.ProducerInfo; 6 | import io.github.ncasaux.camelplantuml.model.RouteInfo; 7 | import io.github.ncasaux.camelplantuml.model.query.Parameters; 8 | import io.github.ncasaux.camelplantuml.processor.GetRoutesInfoProcessor; 9 | import org.apache.commons.codec.digest.DigestUtils; 10 | import org.apache.commons.io.IOUtils; 11 | import org.apache.commons.lang3.StringUtils; 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | 15 | import java.io.IOException; 16 | import java.net.URI; 17 | import java.net.URISyntaxException; 18 | import java.nio.charset.StandardCharsets; 19 | import java.util.ArrayList; 20 | import java.util.Arrays; 21 | import java.util.HashMap; 22 | import java.util.Objects; 23 | 24 | public class ConsumersDiagramGenerator { 25 | 26 | private static final Logger LOGGER = LoggerFactory.getLogger(ConsumersDiagramGenerator.class); 27 | 28 | public static String generateUmlString(ArrayList consumersInfo, 29 | ArrayList producersInfo, 30 | HashMap endpointBaseUrisInfo, 31 | HashMap routesInfo, 32 | Parameters parameters) throws IOException, URISyntaxException { 33 | 34 | String umlConsumerTemplate = IOUtils.toString(Objects.requireNonNull(ConsumersDiagramGenerator.class.getClassLoader().getResourceAsStream("plantuml/consumerTemplate")), StandardCharsets.UTF_8); 35 | String umlDynamicConsumerRouteTemplate = IOUtils.toString(Objects.requireNonNull(ConsumersDiagramGenerator.class.getClassLoader().getResourceAsStream("plantuml/dynamicConsumerTemplate")), StandardCharsets.UTF_8); 36 | String umlString = ""; 37 | 38 | for (ConsumerInfo consumerInfo : consumersInfo) { 39 | String routeId = consumerInfo.getRouteId(); 40 | String processorType = consumerInfo.getProcessorType(); 41 | String endpointBaseUri = consumerInfo.getEndpointUri(); 42 | String routeElementId = routesInfo.get(routeId).getDiagramElementId(); 43 | String routeEndpointBaseUri = routesInfo.get(routeId).getEndpointBaseUri(); 44 | 45 | boolean drawConsumer = true; 46 | 47 | for (String routeIdFilter : GetRoutesInfoProcessor.routeIdFilters) { 48 | if (routeId.matches(routeIdFilter)) { 49 | drawConsumer = false; 50 | LOGGER.info("{} matches the routeId filter \"{}\", consumer will not be part of the diagram", consumerInfo, routeIdFilter); 51 | break; 52 | } 53 | } 54 | 55 | for (String endpointBaseUriFilter : GetRoutesInfoProcessor.endpointBaseUriFilters) { 56 | if (routeEndpointBaseUri.matches(endpointBaseUriFilter)) { 57 | drawConsumer = false; 58 | LOGGER.info("{} matches the endpoint filter \"{}\", consumer will not be part of the diagram", consumerInfo, endpointBaseUriFilter); 59 | break; 60 | } 61 | } 62 | 63 | if (parameters.uriFilterPattern().matcher(endpointBaseUri).matches()) { 64 | drawConsumer = false; 65 | LOGGER.info("{} matches the uriFilterPattern \"{}\", consumer will not be part of the diagram", consumerInfo, parameters.uriFilterPattern()); 66 | } 67 | 68 | if (parameters.connectRoutes() && producersInfo.stream().anyMatch(producerInfo -> producerInfo.getEndpointUri().equals(endpointBaseUri)) && Arrays.asList(GetRoutesInfoProcessor.camelInternalEndpointSchemeFilters).contains(new URI(endpointBaseUri).getScheme())) { 69 | drawConsumer = false; 70 | LOGGER.info("Parameter \"connectRoutes\" is \"true\", consumer in routeId \"{}\" from internal endpointBaseUri \"{}\" will not be part of the diagram", routeId, endpointBaseUri); 71 | } 72 | 73 | if (drawConsumer) { 74 | if (!consumerInfo.getUseDynamicEndpoint()) { 75 | String endpointElementId = endpointBaseUrisInfo.get(endpointBaseUri).getDiagramElementId(); 76 | 77 | umlString = umlString 78 | .concat(StringUtils.replaceEach(umlConsumerTemplate, 79 | new String[]{"%%endpointElementId%%", "%%routeElementId%%", "%%processorType%%"}, 80 | new String[]{endpointElementId, routeElementId, processorType})) 81 | .concat("\n\n"); 82 | 83 | } else { 84 | String uri = consumerInfo.getEndpointUri(); 85 | String endpointElementId = "dynamic_consumer_endpoint_".concat(DigestUtils.md5Hex(uri)); 86 | 87 | umlString = umlString 88 | .concat(StringUtils.replaceEach(umlDynamicConsumerRouteTemplate, 89 | new String[]{"%%endpointElementId%%", "%%uri%%", "%%routeElementId%%", "%%processorType%%"}, 90 | new String[]{endpointElementId, uri, routeElementId, processorType})) 91 | .concat("\n\n") 92 | ; 93 | } 94 | } 95 | } 96 | return umlString; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/main/java/io/github/ncasaux/camelplantuml/generator/ProducersDiagramGenerator.java: -------------------------------------------------------------------------------- 1 | package io.github.ncasaux.camelplantuml.generator; 2 | 3 | import io.github.ncasaux.camelplantuml.model.ConsumerInfo; 4 | import io.github.ncasaux.camelplantuml.model.EndpointBaseUriInfo; 5 | import io.github.ncasaux.camelplantuml.model.ProducerInfo; 6 | import io.github.ncasaux.camelplantuml.model.RouteInfo; 7 | import io.github.ncasaux.camelplantuml.model.query.Parameters; 8 | import io.github.ncasaux.camelplantuml.processor.GetRoutesInfoProcessor; 9 | import org.apache.commons.codec.digest.DigestUtils; 10 | import org.apache.commons.io.IOUtils; 11 | import org.apache.commons.lang3.StringUtils; 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | 15 | import java.io.IOException; 16 | import java.net.URI; 17 | import java.net.URISyntaxException; 18 | import java.nio.charset.StandardCharsets; 19 | import java.util.*; 20 | 21 | public class ProducersDiagramGenerator { 22 | 23 | private static final Logger LOGGER = LoggerFactory.getLogger(ProducersDiagramGenerator.class); 24 | 25 | public static String generateUmlString(ArrayList consumersInfo, 26 | ArrayList producersInfo, 27 | HashMap endpointBaseUrisInfo, 28 | HashMap routesInfo, 29 | Parameters parameters) throws IOException, URISyntaxException { 30 | 31 | String umlProducerTemplate = IOUtils.toString(Objects.requireNonNull(ProducersDiagramGenerator.class.getClassLoader().getResourceAsStream("plantuml/producerTemplate")), StandardCharsets.UTF_8); 32 | String umlDynamicProducerRouteTemplate = IOUtils.toString(Objects.requireNonNull(ProducersDiagramGenerator.class.getClassLoader().getResourceAsStream("plantuml/dynamicProducerTemplate")), StandardCharsets.UTF_8); 33 | String umlString = ""; 34 | 35 | for (ProducerInfo producerInfo : producersInfo) { 36 | 37 | String routeId = producerInfo.getRouteId(); 38 | String processorType = producerInfo.getProcessorType(); 39 | String endpointBaseUri = producerInfo.getEndpointUri(); 40 | String routeElementId = routesInfo.get(routeId).getDiagramElementId(); 41 | String routeEndpointBaseUri = routesInfo.get(routeId).getEndpointBaseUri(); 42 | 43 | boolean drawProducer = true; 44 | 45 | for (String routeIdFilter : GetRoutesInfoProcessor.routeIdFilters) { 46 | if (routeId.matches(routeIdFilter)) { 47 | drawProducer = false; 48 | LOGGER.info("{} matches the routeId filter \"{}\", producer will not be part of the diagram", producerInfo, routeIdFilter); 49 | break; 50 | } 51 | } 52 | 53 | for (String endpointBaseUriFilter : GetRoutesInfoProcessor.endpointBaseUriFilters) { 54 | if (routeEndpointBaseUri.matches(endpointBaseUriFilter)) { 55 | drawProducer = false; 56 | LOGGER.info("{} matches the endpoint filter \"{}\", producer will not be part of the diagram", producerInfo, endpointBaseUriFilter); 57 | break; 58 | } 59 | } 60 | 61 | if (parameters.uriFilterPattern().matcher(routeEndpointBaseUri).matches() || parameters.uriFilterPattern().matcher(endpointBaseUri).matches()) { 62 | drawProducer = false; 63 | LOGGER.info("{} matches the uriFilterPattern \"{}\", producer will not be part of the diagram", producerInfo, parameters.uriFilterPattern()); 64 | } 65 | 66 | if (drawProducer) { 67 | if (!producerInfo.getUseDynamicEndpoint()) { 68 | String targetElementId = endpointBaseUrisInfo.get(endpointBaseUri).getDiagramElementId(); 69 | if (parameters.connectRoutes() && Arrays.asList(GetRoutesInfoProcessor.camelInternalEndpointSchemeFilters).contains(new URI(endpointBaseUri).getScheme())) { 70 | ConsumerInfo ci = consumersInfo.stream().filter(consumerInfo -> consumerInfo.getEndpointUri().equals(endpointBaseUri)).findFirst().orElse(null); 71 | if (ci != null) { 72 | processorType = processorType.concat(" / ").concat(ci.getProcessorType()); 73 | targetElementId = routesInfo.get(ci.getRouteId()).getDiagramElementId(); 74 | LOGGER.info("Parameter \"connectRoutes\" is \"true\", producer in routeId \"{}\" will be directly connected to routeId \"{}\", bypassing internal endpointBaseUri \"{}\"", routeId, ci.getRouteId(), endpointBaseUri); 75 | } 76 | } 77 | 78 | umlString = umlString 79 | .concat(StringUtils.replaceEach(umlProducerTemplate, 80 | new String[]{"%%targetElementId%%", "%%routeElementId%%", "%%processorType%%"}, 81 | new String[]{targetElementId, routeElementId, processorType})) 82 | .concat("\n\n"); 83 | 84 | } else { 85 | String uri = producerInfo.getEndpointUri(); 86 | String endpointElementId = "dynamic_producer_endpoint_".concat(DigestUtils.md5Hex(uri)); 87 | 88 | umlString = umlString 89 | .concat(StringUtils.replaceEach(umlDynamicProducerRouteTemplate, 90 | new String[]{"%%endpointElementId%%", "%%uri%%", "%%routeElementId%%", "%%processorType%%"}, 91 | new String[]{endpointElementId, uri, routeElementId, processorType})) 92 | .concat("\n\n") 93 | ; 94 | } 95 | } 96 | } 97 | return umlString; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/test/java/DefaultExample/DefaultExampleWithConnectRoutesTest.java: -------------------------------------------------------------------------------- 1 | package DefaultExample; 2 | 3 | import io.github.ncasaux.camelplantuml.routebuilder.CamelPlantUmlRouteBuilder; 4 | import org.apache.camel.LoggingLevel; 5 | import org.apache.camel.RoutesBuilder; 6 | import org.apache.camel.builder.AdviceWith; 7 | import org.apache.camel.builder.RouteBuilder; 8 | import org.apache.camel.component.mock.MockEndpoint; 9 | import org.apache.camel.test.junit5.CamelTestSupport; 10 | import org.junit.jupiter.api.Test; 11 | 12 | import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.*; 13 | 14 | public class DefaultExampleWithConnectRoutesTest extends CamelTestSupport { 15 | 16 | @Override 17 | public boolean isUseAdviceWith() { 18 | return true; 19 | } 20 | 21 | @Override 22 | public boolean useJmx() { 23 | return true; 24 | } 25 | 26 | @Test 27 | public void testMock() throws Exception { 28 | MockEndpoint mock = getMockEndpoint("mock:camel-plantuml-output"); 29 | 30 | 31 | mock.expectedBodiesReceived("@startuml\n" + 32 | "\n" + 33 | "skinparam ArrowColor #Black\n" + 34 | "\n" + 35 | "skinparam rectangle {\n" + 36 | " RoundCorner 20\n" + 37 | "}\n" + 38 | "\n" + 39 | "skinparam rectangle<> {\n" + 40 | " BorderColor #6C8EBF\n" + 41 | " BackgroundColor #DAE8FC\n" + 42 | "}\n" + 43 | "\n" + 44 | "skinparam queue<> {\n" + 45 | "}\n" + 46 | "\n" + 47 | "skinparam queue<> {\n" + 48 | " BorderColor #B85450\n" + 49 | " BackgroundColor #F8CECC\n" + 50 | "}\n" + 51 | "\n" + 52 | "skinparam queue<> {\n" + 53 | " BorderColor #82B366\n" + 54 | " BackgroundColor #D5E8D4\n" + 55 | "}\n" + 56 | "\n" + 57 | "footer Generated with camel-plantuml on %date(\"dd-MM-yyyy HH:mm\")\n" + 58 | "\n" + 59 | "' === Some useful settings for tweaking diagram layout ===\n" + 60 | "'left to right direction\n" + 61 | "'hide stereotype\n" + 62 | "'skinparam nodesep 50\n" + 63 | "'skinparam ranksep 50\n" + 64 | "'skinparam wrapWidth 250\n" + 65 | "\n" + 66 | "rectangle route_2ad9f14c90052cf9002f79d5f9fa54cb <> as \"\n" + 67 | "mainRoute\n" + 68 | "....\n" + 69 | "Route which handles processing of the message\n" + 70 | "\"\n" + 71 | "\n" + 72 | "rectangle route_a4212b7daeffab7a6859963fce8df0c1 <> as \"\n" + 73 | "fastTimerRoute\n" + 74 | "....\n" + 75 | "Route which generates fast periodic events\n" + 76 | "\"\n" + 77 | "\n" + 78 | "rectangle route_2c3a25b7f186d9a06118c863dc529551 <> as \"\n" + 79 | "transformRoute\n" + 80 | "....\n" + 81 | "Route which transforms the message\n" + 82 | "\"\n" + 83 | "\n" + 84 | "rectangle route_e75ae82e12c615feefaf77105cf18e63 <> as \"\n" + 85 | "slowTimerRoute\n" + 86 | "....\n" + 87 | "Route which generates slow periodic events\n" + 88 | "\"\n" + 89 | "\n" + 90 | "queue endpoint_c1749b7ed34e5395932c33f971ca4151 <><> as \"\n" + 91 | "timer://foo\n" + 92 | "\"\n" + 93 | "\n" + 94 | "queue endpoint_497a674fd655c44f28111e246619dc57 <><> as \"\n" + 95 | "timer://bar\n" + 96 | "\"\n" + 97 | "\n" + 98 | "endpoint_497a674fd655c44f28111e246619dc57 --> route_a4212b7daeffab7a6859963fce8df0c1 : from\n" + 99 | "\n" + 100 | "endpoint_c1749b7ed34e5395932c33f971ca4151 --> route_e75ae82e12c615feefaf77105cf18e63 : from\n" + 101 | "\n" + 102 | "route_e75ae82e12c615feefaf77105cf18e63 --> route_2ad9f14c90052cf9002f79d5f9fa54cb : to / from\n" + 103 | "\n" + 104 | "route_a4212b7daeffab7a6859963fce8df0c1 --> route_2ad9f14c90052cf9002f79d5f9fa54cb : to / from\n" + 105 | "\n" + 106 | "queue dynamic_producer_endpoint_1846cdc72007895e6140e286368e7049 <><> as \"\n" + 107 | "mock://mock-${body}\n" + 108 | "\"\n" + 109 | "\n" + 110 | "route_2ad9f14c90052cf9002f79d5f9fa54cb --> dynamic_producer_endpoint_1846cdc72007895e6140e286368e7049 : toD\n" + 111 | "\n" + 112 | "route_2ad9f14c90052cf9002f79d5f9fa54cb --> route_2c3a25b7f186d9a06118c863dc529551 : enrich / from\n" + 113 | "\n" + 114 | "@enduml\n"); 115 | 116 | AdviceWith.adviceWith(context, "camel-plantuml-http-trigger", a -> { 117 | a.weaveAddLast().transform(a.body().regexReplaceAll("\r", "")); 118 | a.weaveAddLast().to("mock:camel-plantuml-output"); 119 | } 120 | ); 121 | 122 | context.start(); 123 | 124 | template.sendBodyAndHeader("direct:camel-plantuml-generate-plantuml", null, "connectRoutes",true); 125 | MockEndpoint.assertIsSatisfied(context); 126 | } 127 | 128 | @Override 129 | protected RoutesBuilder createRouteBuilder() { 130 | return new RouteBuilder() { 131 | @Override 132 | public void configure() throws Exception { 133 | from(timer("foo").period(5000)).routeId("slowTimerRoute") 134 | .description("Route which generates slow periodic events") 135 | .setBody(constant("slow")) 136 | .to(seda("endpoint1")).id("_to01"); 137 | 138 | from(timer("bar").period(1000)).routeId("fastTimerRoute") 139 | .description("Route which generates fast periodic events") 140 | .setBody(constant("fast")) 141 | .to(seda("endpoint1")).id("_to02"); 142 | 143 | from(seda("endpoint1")).routeId("mainRoute") 144 | .description("Route which handles processing of the message") 145 | .log(LoggingLevel.INFO, "${body}") 146 | .enrich().constant("direct://endpoint2").id("_enrich01") 147 | .toD(mock("mock-${body}")).id("_toD01"); 148 | 149 | from(direct("endpoint2")).routeId("transformRoute") 150 | .description("Route which transforms the message") 151 | .transform(simple("${body}${body}")); 152 | 153 | getContext().addRoutes(new CamelPlantUmlRouteBuilder()); 154 | 155 | } 156 | 157 | }; 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 4.0.0 6 | 7 | io.github.ncasaux 8 | camel-plantuml 9 | pom 10 | 1.8.0 11 | 12 | camel-plantuml-jar 13 | camel-plantuml-zip 14 | 15 | 16 | A project to generate PlantUML diagrams from Camel routes 17 | camel-plantuml allows to generate PlantUML diagrams from deployed Camel routes 18 | https://github.com/ncasaux/camel-plantuml 19 | 20 | 21 | 22 | The MIT License 23 | https://opensource.org/licenses/MIT 24 | repo 25 | 26 | 27 | 28 | 29 | 30 | ncasaux 31 | Nicolas Casaux 32 | http://www.github.com/ncasaux 33 | nicolas.casaux@outlook.com 34 | 35 | 36 | 37 | 38 | scm:git:git://github.com/ncasaux/camel-plantuml.git 39 | scm:git:ssh://github.com/ncasaux/camel-plantuml.git 40 | https://github.com/ncasaux/camel-plantuml.git 41 | 42 | 43 | 44 | 45 | ossrh 46 | https://s01.oss.sonatype.org/content/repositories/snapshots 47 | 48 | 49 | ossrh 50 | https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/ 51 | 52 | 53 | 54 | 55 | UTF-8 56 | UTF-8 57 | 58 | 59 | 60 | 61 | 62 | 63 | org.apache.camel 64 | camel-bom 65 | 4.4.1 66 | import 67 | pom 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | org.apache.camel 77 | camel-core 78 | 79 | 80 | org.apache.camel 81 | camel-main 82 | 83 | 84 | org.apache.camel 85 | camel-endpointdsl 86 | 87 | 88 | org.apache.camel 89 | camel-rest 90 | 91 | 92 | org.apache.camel 93 | camel-netty-http 94 | 95 | 96 | org.apache.camel 97 | camel-management 98 | 99 | 100 | org.apache.camel 101 | camel-test-junit5 102 | test 103 | 104 | 105 | 106 | org.apache.logging.log4j 107 | log4j-slf4j-impl 108 | runtime 109 | 2.23.1 110 | 111 | 112 | 113 | 114 | org.apache.commons 115 | commons-lang3 116 | 3.14.0 117 | 118 | 119 | org.apache.commons 120 | commons-collections4 121 | 4.4 122 | 123 | 124 | commons-codec 125 | commons-codec 126 | 1.16.1 127 | 128 | 129 | 130 | 131 | commons-io 132 | commons-io 133 | 2.16.1 134 | 135 | 136 | 137 | 138 | 139 | install 140 | 141 | 142 | 143 | org.apache.maven.plugins 144 | maven-compiler-plugin 145 | 3.12.1 146 | 147 | 17 148 | 17 149 | 150 | 151 | 152 | org.apache.maven.plugins 153 | maven-source-plugin 154 | 3.3.0 155 | 156 | 157 | attach-sources 158 | 159 | jar-no-fork 160 | 161 | 162 | 163 | 164 | 165 | org.apache.maven.plugins 166 | maven-javadoc-plugin 167 | 3.6.3 168 | 169 | 170 | attach-javadocs 171 | 172 | jar 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | maven_central 182 | Maven Central 183 | https://repo.maven.apache.org/maven2/ 184 | 185 | 186 | 187 | 188 | 189 | ci-cd 190 | 191 | 192 | 193 | org.apache.maven.plugins 194 | maven-gpg-plugin 195 | 3.1.0 196 | 197 | 198 | sign-artifacts 199 | verify 200 | 201 | sign 202 | 203 | 204 | 206 | 207 | --pinentry-mode 208 | loopback 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/test/java/DefaultExample/DefaultExampleWithUriFilterPatternTest.java: -------------------------------------------------------------------------------- 1 | package DefaultExample; 2 | 3 | import io.github.ncasaux.camelplantuml.routebuilder.CamelPlantUmlRouteBuilder; 4 | import org.apache.camel.LoggingLevel; 5 | import org.apache.camel.RoutesBuilder; 6 | import org.apache.camel.builder.AdviceWith; 7 | import org.apache.camel.builder.RouteBuilder; 8 | import org.apache.camel.component.mock.MockEndpoint; 9 | import org.apache.camel.test.junit5.CamelTestSupport; 10 | import org.junit.jupiter.api.Test; 11 | 12 | import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.direct; 13 | import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.mock; 14 | import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.seda; 15 | import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.timer; 16 | 17 | public class DefaultExampleWithUriFilterPatternTest extends CamelTestSupport { 18 | 19 | @Override 20 | public boolean isUseAdviceWith() { 21 | return true; 22 | } 23 | 24 | @Override 25 | public boolean useJmx() { 26 | return true; 27 | } 28 | 29 | @Test 30 | public void testMock() throws Exception { 31 | MockEndpoint mock = getMockEndpoint("mock:camel-plantuml-output"); 32 | 33 | 34 | mock.expectedBodiesReceived("@startuml\n" + 35 | "\n" + 36 | "skinparam ArrowColor #Black\n" + 37 | "\n" + 38 | "skinparam rectangle {\n" + 39 | " RoundCorner 20\n" + 40 | "}\n" + 41 | "\n" + 42 | "skinparam rectangle<> {\n" + 43 | " BorderColor #6C8EBF\n" + 44 | " BackgroundColor #DAE8FC\n" + 45 | "}\n" + 46 | "\n" + 47 | "skinparam queue<> {\n" + 48 | "}\n" + 49 | "\n" + 50 | "skinparam queue<> {\n" + 51 | " BorderColor #B85450\n" + 52 | " BackgroundColor #F8CECC\n" + 53 | "}\n" + 54 | "\n" + 55 | "skinparam queue<> {\n" + 56 | " BorderColor #82B366\n" + 57 | " BackgroundColor #D5E8D4\n" + 58 | "}\n" + 59 | "\n" + 60 | "footer Generated with camel-plantuml on %date(\"dd-MM-yyyy HH:mm\")\n" + 61 | "\n" + 62 | "' === Some useful settings for tweaking diagram layout ===\n" + 63 | "'left to right direction\n" + 64 | "'hide stereotype\n" + 65 | "'skinparam nodesep 50\n" + 66 | "'skinparam ranksep 50\n" + 67 | "'skinparam wrapWidth 250\n" + 68 | "\n" + 69 | "rectangle route_2ad9f14c90052cf9002f79d5f9fa54cb <> as \"\n" + 70 | "mainRoute\n" + 71 | "....\n" + 72 | "Route which handles processing of the message\n" + 73 | "\"\n" + 74 | "\n" + 75 | "rectangle route_a4212b7daeffab7a6859963fce8df0c1 <> as \"\n" + 76 | "fastTimerRoute\n" + 77 | "....\n" + 78 | "Route which generates fast periodic events\n" + 79 | "\"\n" + 80 | "\n" + 81 | "rectangle route_2c3a25b7f186d9a06118c863dc529551 <> as \"\n" + 82 | "transformRoute\n" + 83 | "....\n" + 84 | "Route which transforms the message\n" + 85 | "\"\n" + 86 | "\n" + 87 | "queue endpoint_9259e64c942ad21bc3beebab69d91941 <><> as \"\n" + 88 | "seda://endpoint1\n" + 89 | "\"\n" + 90 | "\n" + 91 | "queue endpoint_497a674fd655c44f28111e246619dc57 <><> as \"\n" + 92 | "timer://bar\n" + 93 | "\"\n" + 94 | "\n" + 95 | "queue endpoint_766e5055e2b624afb926345d34208088 <><> as \"\n" + 96 | "direct://endpoint2\n" + 97 | "\"\n" + 98 | "\n" + 99 | "endpoint_497a674fd655c44f28111e246619dc57 --> route_a4212b7daeffab7a6859963fce8df0c1 : from\n" + 100 | "\n" + 101 | "endpoint_9259e64c942ad21bc3beebab69d91941 --> route_2ad9f14c90052cf9002f79d5f9fa54cb : from\n" + 102 | "\n" + 103 | "endpoint_766e5055e2b624afb926345d34208088 --> route_2c3a25b7f186d9a06118c863dc529551 : from\n" + 104 | "\n" + 105 | "route_a4212b7daeffab7a6859963fce8df0c1 --> endpoint_9259e64c942ad21bc3beebab69d91941 : to\n" + 106 | "\n" + 107 | "queue dynamic_producer_endpoint_1846cdc72007895e6140e286368e7049 <><> as \"\n" + 108 | "mock://mock-${body}\n" + 109 | "\"\n" + 110 | "\n" + 111 | "route_2ad9f14c90052cf9002f79d5f9fa54cb --> dynamic_producer_endpoint_1846cdc72007895e6140e286368e7049 : toD\n" + 112 | "\n" + 113 | "route_2ad9f14c90052cf9002f79d5f9fa54cb --> endpoint_766e5055e2b624afb926345d34208088 : enrich\n" + 114 | "\n" + 115 | "@enduml\n"); 116 | 117 | AdviceWith.adviceWith(context, "camel-plantuml-http-trigger", a -> { 118 | a.weaveAddLast().transform(a.body().regexReplaceAll("\r", "")); 119 | a.weaveAddLast().to("mock:camel-plantuml-output"); 120 | } 121 | ); 122 | 123 | context.start(); 124 | 125 | template.sendBodyAndHeader("direct:camel-plantuml-generate-plantuml", null, "uriFilterPattern",".*foo.*"); 126 | MockEndpoint.assertIsSatisfied(context); 127 | } 128 | 129 | @Override 130 | protected RoutesBuilder createRouteBuilder() { 131 | return new RouteBuilder() { 132 | @Override 133 | public void configure() throws Exception { 134 | from(timer("foo").period(5000)).routeId("slowTimerRoute") 135 | .description("Route which generates slow periodic events") 136 | .setBody(constant("slow")) 137 | .to(seda("endpoint1")).id("_to01"); 138 | 139 | from(timer("bar").period(1000)).routeId("fastTimerRoute") 140 | .description("Route which generates fast periodic events") 141 | .setBody(constant("fast")) 142 | .to(seda("endpoint1")).id("_to02"); 143 | 144 | from(seda("endpoint1")).routeId("mainRoute") 145 | .description("Route which handles processing of the message") 146 | .log(LoggingLevel.INFO, "${body}") 147 | .enrich().constant("direct://endpoint2").id("_enrich01") 148 | .toD(mock("mock-${body}")).id("_toD01"); 149 | 150 | from(direct("endpoint2")).routeId("transformRoute") 151 | .description("Route which transforms the message") 152 | .transform(simple("${body}${body}")); 153 | 154 | getContext().addRoutes(new CamelPlantUmlRouteBuilder()); 155 | 156 | } 157 | 158 | }; 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/test/java/DefaultExample/DefaultExampleTest.java: -------------------------------------------------------------------------------- 1 | package DefaultExample; 2 | 3 | import io.github.ncasaux.camelplantuml.routebuilder.CamelPlantUmlRouteBuilder; 4 | import org.apache.camel.LoggingLevel; 5 | import org.apache.camel.RoutesBuilder; 6 | import org.apache.camel.builder.AdviceWith; 7 | import org.apache.camel.builder.RouteBuilder; 8 | import org.apache.camel.component.mock.MockEndpoint; 9 | import org.apache.camel.test.junit5.CamelTestSupport; 10 | import org.junit.jupiter.api.Test; 11 | 12 | import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.*; 13 | 14 | public class DefaultExampleTest extends CamelTestSupport { 15 | 16 | @Override 17 | public boolean isUseAdviceWith() { 18 | return true; 19 | } 20 | 21 | @Override 22 | public boolean useJmx() { 23 | return true; 24 | } 25 | 26 | @Test 27 | public void testMock() throws Exception { 28 | MockEndpoint mock = getMockEndpoint("mock:camel-plantuml-output"); 29 | 30 | 31 | mock.expectedBodiesReceived("@startuml\n" + 32 | "\n" + 33 | "skinparam ArrowColor #Black\n" + 34 | "\n" + 35 | "skinparam rectangle {\n" + 36 | " RoundCorner 20\n" + 37 | "}\n" + 38 | "\n" + 39 | "skinparam rectangle<> {\n" + 40 | " BorderColor #6C8EBF\n" + 41 | " BackgroundColor #DAE8FC\n" + 42 | "}\n" + 43 | "\n" + 44 | "skinparam queue<> {\n" + 45 | "}\n" + 46 | "\n" + 47 | "skinparam queue<> {\n" + 48 | " BorderColor #B85450\n" + 49 | " BackgroundColor #F8CECC\n" + 50 | "}\n" + 51 | "\n" + 52 | "skinparam queue<> {\n" + 53 | " BorderColor #82B366\n" + 54 | " BackgroundColor #D5E8D4\n" + 55 | "}\n" + 56 | "\n" + 57 | "footer Generated with camel-plantuml on %date(\"dd-MM-yyyy HH:mm\")\n" + 58 | "\n" + 59 | "' === Some useful settings for tweaking diagram layout ===\n" + 60 | "'left to right direction\n" + 61 | "'hide stereotype\n" + 62 | "'skinparam nodesep 50\n" + 63 | "'skinparam ranksep 50\n" + 64 | "'skinparam wrapWidth 250\n" + 65 | "\n" + 66 | "rectangle route_2ad9f14c90052cf9002f79d5f9fa54cb <> as \"\n" + 67 | "mainRoute\n" + 68 | "....\n" + 69 | "Route which handles processing of the message\n" + 70 | "\"\n" + 71 | "\n" + 72 | "rectangle route_a4212b7daeffab7a6859963fce8df0c1 <> as \"\n" + 73 | "fastTimerRoute\n" + 74 | "....\n" + 75 | "Route which generates fast periodic events\n" + 76 | "\"\n" + 77 | "\n" + 78 | "rectangle route_2c3a25b7f186d9a06118c863dc529551 <> as \"\n" + 79 | "transformRoute\n" + 80 | "....\n" + 81 | "Route which transforms the message\n" + 82 | "\"\n" + 83 | "\n" + 84 | "rectangle route_e75ae82e12c615feefaf77105cf18e63 <> as \"\n" + 85 | "slowTimerRoute\n" + 86 | "....\n" + 87 | "Route which generates slow periodic events\n" + 88 | "\"\n" + 89 | "\n" + 90 | "queue endpoint_9259e64c942ad21bc3beebab69d91941 <><> as \"\n" + 91 | "seda://endpoint1\n" + 92 | "\"\n" + 93 | "\n" + 94 | "queue endpoint_c1749b7ed34e5395932c33f971ca4151 <><> as \"\n" + 95 | "timer://foo\n" + 96 | "\"\n" + 97 | "\n" + 98 | "queue endpoint_497a674fd655c44f28111e246619dc57 <><> as \"\n" + 99 | "timer://bar\n" + 100 | "\"\n" + 101 | "\n" + 102 | "queue endpoint_766e5055e2b624afb926345d34208088 <><> as \"\n" + 103 | "direct://endpoint2\n" + 104 | "\"\n" + 105 | "\n" + 106 | "endpoint_497a674fd655c44f28111e246619dc57 --> route_a4212b7daeffab7a6859963fce8df0c1 : from\n" + 107 | "\n" + 108 | "endpoint_9259e64c942ad21bc3beebab69d91941 --> route_2ad9f14c90052cf9002f79d5f9fa54cb : from\n" + 109 | "\n" + 110 | "endpoint_c1749b7ed34e5395932c33f971ca4151 --> route_e75ae82e12c615feefaf77105cf18e63 : from\n" + 111 | "\n" + 112 | "endpoint_766e5055e2b624afb926345d34208088 --> route_2c3a25b7f186d9a06118c863dc529551 : from\n" + 113 | "\n" + 114 | "route_e75ae82e12c615feefaf77105cf18e63 --> endpoint_9259e64c942ad21bc3beebab69d91941 : to\n" + 115 | "\n" + 116 | "route_a4212b7daeffab7a6859963fce8df0c1 --> endpoint_9259e64c942ad21bc3beebab69d91941 : to\n" + 117 | "\n" + 118 | "queue dynamic_producer_endpoint_1846cdc72007895e6140e286368e7049 <><> as \"\n" + 119 | "mock://mock-${body}\n" + 120 | "\"\n" + 121 | "\n" + 122 | "route_2ad9f14c90052cf9002f79d5f9fa54cb --> dynamic_producer_endpoint_1846cdc72007895e6140e286368e7049 : toD\n" + 123 | "\n" + 124 | "route_2ad9f14c90052cf9002f79d5f9fa54cb --> endpoint_766e5055e2b624afb926345d34208088 : enrich\n" + 125 | "\n" + 126 | "@enduml\n"); 127 | 128 | AdviceWith.adviceWith(context, "camel-plantuml-http-trigger", a -> { 129 | a.weaveAddLast().transform(a.body().regexReplaceAll("\r", "")); 130 | a.weaveAddLast().to("mock:camel-plantuml-output"); 131 | } 132 | ); 133 | 134 | context.start(); 135 | 136 | template.sendBody("direct:camel-plantuml-generate-plantuml", null); 137 | MockEndpoint.assertIsSatisfied(context); 138 | } 139 | 140 | @Override 141 | protected RoutesBuilder createRouteBuilder() { 142 | return new RouteBuilder() { 143 | @Override 144 | public void configure() throws Exception { 145 | from(timer("foo").period(5000)).routeId("slowTimerRoute") 146 | .description("Route which generates slow periodic events") 147 | .setBody(constant("slow")) 148 | .to(seda("endpoint1")).id("_to01"); 149 | 150 | from(timer("bar").period(1000)).routeId("fastTimerRoute") 151 | .description("Route which generates fast periodic events") 152 | .setBody(constant("fast")) 153 | .to(seda("endpoint1")).id("_to02"); 154 | 155 | from(seda("endpoint1")).routeId("mainRoute") 156 | .description("Route which handles processing of the message") 157 | .log(LoggingLevel.INFO, "${body}") 158 | .enrich().constant("direct://endpoint2").id("_enrich01") 159 | .toD(mock("mock-${body}")).id("_toD01"); 160 | 161 | from(direct("endpoint2")).routeId("transformRoute") 162 | .description("Route which transforms the message") 163 | .transform(simple("${body}${body}")); 164 | 165 | getContext().addRoutes(new CamelPlantUmlRouteBuilder()); 166 | 167 | } 168 | 169 | }; 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/test/java/DefaultExample/DefaultExampleWithHostAndPortTest.java: -------------------------------------------------------------------------------- 1 | package DefaultExample; 2 | 3 | import io.github.ncasaux.camelplantuml.routebuilder.CamelPlantUmlRouteBuilder; 4 | import org.apache.camel.LoggingLevel; 5 | import org.apache.camel.RoutesBuilder; 6 | import org.apache.camel.builder.AdviceWith; 7 | import org.apache.camel.builder.RouteBuilder; 8 | import org.apache.camel.component.mock.MockEndpoint; 9 | import org.apache.camel.test.junit5.CamelTestSupport; 10 | import org.junit.jupiter.api.Test; 11 | 12 | import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.*; 13 | 14 | public class DefaultExampleWithHostAndPortTest extends CamelTestSupport { 15 | 16 | @Override 17 | public boolean isUseAdviceWith() { 18 | return true; 19 | } 20 | 21 | @Override 22 | public boolean useJmx() { 23 | return true; 24 | } 25 | 26 | @Test 27 | public void testMock() throws Exception { 28 | MockEndpoint mock = getMockEndpoint("mock:camel-plantuml-output"); 29 | 30 | 31 | mock.expectedBodiesReceived("@startuml\n" + 32 | "\n" + 33 | "skinparam ArrowColor #Black\n" + 34 | "\n" + 35 | "skinparam rectangle {\n" + 36 | " RoundCorner 20\n" + 37 | "}\n" + 38 | "\n" + 39 | "skinparam rectangle<> {\n" + 40 | " BorderColor #6C8EBF\n" + 41 | " BackgroundColor #DAE8FC\n" + 42 | "}\n" + 43 | "\n" + 44 | "skinparam queue<> {\n" + 45 | "}\n" + 46 | "\n" + 47 | "skinparam queue<> {\n" + 48 | " BorderColor #B85450\n" + 49 | " BackgroundColor #F8CECC\n" + 50 | "}\n" + 51 | "\n" + 52 | "skinparam queue<> {\n" + 53 | " BorderColor #82B366\n" + 54 | " BackgroundColor #D5E8D4\n" + 55 | "}\n" + 56 | "\n" + 57 | "footer Generated with camel-plantuml on %date(\"dd-MM-yyyy HH:mm\")\n" + 58 | "\n" + 59 | "' === Some useful settings for tweaking diagram layout ===\n" + 60 | "'left to right direction\n" + 61 | "'hide stereotype\n" + 62 | "'skinparam nodesep 50\n" + 63 | "'skinparam ranksep 50\n" + 64 | "'skinparam wrapWidth 250\n" + 65 | "\n" + 66 | "rectangle route_2ad9f14c90052cf9002f79d5f9fa54cb <> as \"\n" + 67 | "mainRoute\n" + 68 | "....\n" + 69 | "Route which handles processing of the message\n" + 70 | "\"\n" + 71 | "\n" + 72 | "rectangle route_a4212b7daeffab7a6859963fce8df0c1 <> as \"\n" + 73 | "fastTimerRoute\n" + 74 | "....\n" + 75 | "Route which generates fast periodic events\n" + 76 | "\"\n" + 77 | "\n" + 78 | "rectangle route_2c3a25b7f186d9a06118c863dc529551 <> as \"\n" + 79 | "transformRoute\n" + 80 | "....\n" + 81 | "Route which transforms the message\n" + 82 | "\"\n" + 83 | "\n" + 84 | "rectangle route_e75ae82e12c615feefaf77105cf18e63 <> as \"\n" + 85 | "slowTimerRoute\n" + 86 | "....\n" + 87 | "Route which generates slow periodic events\n" + 88 | "\"\n" + 89 | "\n" + 90 | "queue endpoint_9259e64c942ad21bc3beebab69d91941 <><> as \"\n" + 91 | "seda://endpoint1\n" + 92 | "\"\n" + 93 | "\n" + 94 | "queue endpoint_c1749b7ed34e5395932c33f971ca4151 <><> as \"\n" + 95 | "timer://foo\n" + 96 | "\"\n" + 97 | "\n" + 98 | "queue endpoint_497a674fd655c44f28111e246619dc57 <><> as \"\n" + 99 | "timer://bar\n" + 100 | "\"\n" + 101 | "\n" + 102 | "queue endpoint_766e5055e2b624afb926345d34208088 <><> as \"\n" + 103 | "direct://endpoint2\n" + 104 | "\"\n" + 105 | "\n" + 106 | "endpoint_497a674fd655c44f28111e246619dc57 --> route_a4212b7daeffab7a6859963fce8df0c1 : from\n" + 107 | "\n" + 108 | "endpoint_9259e64c942ad21bc3beebab69d91941 --> route_2ad9f14c90052cf9002f79d5f9fa54cb : from\n" + 109 | "\n" + 110 | "endpoint_c1749b7ed34e5395932c33f971ca4151 --> route_e75ae82e12c615feefaf77105cf18e63 : from\n" + 111 | "\n" + 112 | "endpoint_766e5055e2b624afb926345d34208088 --> route_2c3a25b7f186d9a06118c863dc529551 : from\n" + 113 | "\n" + 114 | "route_e75ae82e12c615feefaf77105cf18e63 --> endpoint_9259e64c942ad21bc3beebab69d91941 : to\n" + 115 | "\n" + 116 | "route_a4212b7daeffab7a6859963fce8df0c1 --> endpoint_9259e64c942ad21bc3beebab69d91941 : to\n" + 117 | "\n" + 118 | "queue dynamic_producer_endpoint_1846cdc72007895e6140e286368e7049 <><> as \"\n" + 119 | "mock://mock-${body}\n" + 120 | "\"\n" + 121 | "\n" + 122 | "route_2ad9f14c90052cf9002f79d5f9fa54cb --> dynamic_producer_endpoint_1846cdc72007895e6140e286368e7049 : toD\n" + 123 | "\n" + 124 | "route_2ad9f14c90052cf9002f79d5f9fa54cb --> endpoint_766e5055e2b624afb926345d34208088 : enrich\n" + 125 | "\n" + 126 | "@enduml\n"); 127 | 128 | AdviceWith.adviceWith(context, "camel-plantuml-http-trigger", a -> { 129 | a.weaveAddLast().transform(a.body().regexReplaceAll("\r", "")); 130 | a.weaveAddLast().to("mock:camel-plantuml-output"); 131 | } 132 | ); 133 | 134 | context.start(); 135 | 136 | template.sendBody("direct:camel-plantuml-generate-plantuml", null); 137 | MockEndpoint.assertIsSatisfied(context); 138 | } 139 | 140 | @Override 141 | protected RoutesBuilder createRouteBuilder() { 142 | return new RouteBuilder() { 143 | @Override 144 | public void configure() throws Exception { 145 | from(timer("foo").period(5000)).routeId("slowTimerRoute") 146 | .description("Route which generates slow periodic events") 147 | .setBody(constant("slow")) 148 | .to(seda("endpoint1")).id("_to01"); 149 | 150 | from(timer("bar").period(1000)).routeId("fastTimerRoute") 151 | .description("Route which generates fast periodic events") 152 | .setBody(constant("fast")) 153 | .to(seda("endpoint1")).id("_to02"); 154 | 155 | from(seda("endpoint1")).routeId("mainRoute") 156 | .description("Route which handles processing of the message") 157 | .log(LoggingLevel.INFO, "${body}") 158 | .enrich().constant("direct://endpoint2").id("_enrich01") 159 | .toD(mock("mock-${body}")).id("_toD01"); 160 | 161 | from(direct("endpoint2")).routeId("transformRoute") 162 | .description("Route which transforms the message") 163 | .transform(simple("${body}${body}")); 164 | 165 | getContext().addRoutes(new CamelPlantUmlRouteBuilder("localhost", 9090)); 166 | 167 | } 168 | 169 | }; 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/test/java/DefaultExample/DefaultExampleWithStoppedRouteTest.java: -------------------------------------------------------------------------------- 1 | package DefaultExample; 2 | 3 | import io.github.ncasaux.camelplantuml.routebuilder.CamelPlantUmlRouteBuilder; 4 | import org.apache.camel.LoggingLevel; 5 | import org.apache.camel.RoutesBuilder; 6 | import org.apache.camel.builder.AdviceWith; 7 | import org.apache.camel.builder.RouteBuilder; 8 | import org.apache.camel.component.mock.MockEndpoint; 9 | import org.apache.camel.test.junit5.CamelTestSupport; 10 | import org.junit.jupiter.api.Test; 11 | 12 | import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.*; 13 | 14 | public class DefaultExampleWithStoppedRouteTest extends CamelTestSupport { 15 | 16 | @Override 17 | public boolean isUseAdviceWith() { 18 | return true; 19 | } 20 | 21 | @Override 22 | public boolean useJmx() { 23 | return true; 24 | } 25 | 26 | @Test 27 | public void testMock() throws Exception { 28 | MockEndpoint mock = getMockEndpoint("mock:camel-plantuml-output"); 29 | 30 | 31 | mock.expectedBodiesReceived("@startuml\n" + 32 | "\n" + 33 | "skinparam ArrowColor #Black\n" + 34 | "\n" + 35 | "skinparam rectangle {\n" + 36 | " RoundCorner 20\n" + 37 | "}\n" + 38 | "\n" + 39 | "skinparam rectangle<> {\n" + 40 | " BorderColor #6C8EBF\n" + 41 | " BackgroundColor #DAE8FC\n" + 42 | "}\n" + 43 | "\n" + 44 | "skinparam queue<> {\n" + 45 | "}\n" + 46 | "\n" + 47 | "skinparam queue<> {\n" + 48 | " BorderColor #B85450\n" + 49 | " BackgroundColor #F8CECC\n" + 50 | "}\n" + 51 | "\n" + 52 | "skinparam queue<> {\n" + 53 | " BorderColor #82B366\n" + 54 | " BackgroundColor #D5E8D4\n" + 55 | "}\n" + 56 | "\n" + 57 | "footer Generated with camel-plantuml on %date(\"dd-MM-yyyy HH:mm\")\n" + 58 | "\n" + 59 | "' === Some useful settings for tweaking diagram layout ===\n" + 60 | "'left to right direction\n" + 61 | "'hide stereotype\n" + 62 | "'skinparam nodesep 50\n" + 63 | "'skinparam ranksep 50\n" + 64 | "'skinparam wrapWidth 250\n" + 65 | "\n" + 66 | "rectangle route_2ad9f14c90052cf9002f79d5f9fa54cb <> as \"\n" + 67 | "mainRoute\n" + 68 | "....\n" + 69 | "Route which handles processing of the message\n" + 70 | "\"\n" + 71 | "\n" + 72 | "rectangle route_a4212b7daeffab7a6859963fce8df0c1 <> as \"\n" + 73 | "fastTimerRoute\n" + 74 | "....\n" + 75 | "Route which generates fast periodic events\n" + 76 | "\"\n" + 77 | "\n" + 78 | "rectangle route_2c3a25b7f186d9a06118c863dc529551 <> as \"\n" + 79 | "transformRoute\n" + 80 | "....\n" + 81 | "Route which transforms the message\n" + 82 | "\"\n" + 83 | "\n" + 84 | "rectangle route_e75ae82e12c615feefaf77105cf18e63 <> as \"\n" + 85 | "slowTimerRoute\n" + 86 | "....\n" + 87 | "Route which generates slow periodic events\n" + 88 | "\"\n" + 89 | "\n" + 90 | "queue endpoint_9259e64c942ad21bc3beebab69d91941 <><> as \"\n" + 91 | "seda://endpoint1\n" + 92 | "\"\n" + 93 | "\n" + 94 | "queue endpoint_c1749b7ed34e5395932c33f971ca4151 <><> as \"\n" + 95 | "timer://foo\n" + 96 | "\"\n" + 97 | "\n" + 98 | "queue endpoint_497a674fd655c44f28111e246619dc57 <><> as \"\n" + 99 | "timer://bar\n" + 100 | "\"\n" + 101 | "\n" + 102 | "queue endpoint_766e5055e2b624afb926345d34208088 <><> as \"\n" + 103 | "direct://endpoint2\n" + 104 | "\"\n" + 105 | "\n" + 106 | "endpoint_497a674fd655c44f28111e246619dc57 --> route_a4212b7daeffab7a6859963fce8df0c1 : from\n" + 107 | "\n" + 108 | "endpoint_9259e64c942ad21bc3beebab69d91941 --> route_2ad9f14c90052cf9002f79d5f9fa54cb : from\n" + 109 | "\n" + 110 | "endpoint_c1749b7ed34e5395932c33f971ca4151 --> route_e75ae82e12c615feefaf77105cf18e63 : from\n" + 111 | "\n" + 112 | "endpoint_766e5055e2b624afb926345d34208088 --> route_2c3a25b7f186d9a06118c863dc529551 : from\n" + 113 | "\n" + 114 | "route_e75ae82e12c615feefaf77105cf18e63 --> endpoint_9259e64c942ad21bc3beebab69d91941 : to\n" + 115 | "\n" + 116 | "route_a4212b7daeffab7a6859963fce8df0c1 --> endpoint_9259e64c942ad21bc3beebab69d91941 : to\n" + 117 | "\n" + 118 | "queue dynamic_producer_endpoint_1846cdc72007895e6140e286368e7049 <><> as \"\n" + 119 | "mock://mock-${body}\n" + 120 | "\"\n" + 121 | "\n" + 122 | "route_2ad9f14c90052cf9002f79d5f9fa54cb --> dynamic_producer_endpoint_1846cdc72007895e6140e286368e7049 : toD\n" + 123 | "\n" + 124 | "route_2ad9f14c90052cf9002f79d5f9fa54cb --> endpoint_766e5055e2b624afb926345d34208088 : enrich\n" + 125 | "\n" + 126 | "@enduml\n"); 127 | 128 | AdviceWith.adviceWith(context, "camel-plantuml-http-trigger", a -> { 129 | a.weaveAddLast().transform(a.body().regexReplaceAll("\r", "")); 130 | a.weaveAddLast().to("mock:camel-plantuml-output"); 131 | } 132 | ); 133 | 134 | context.start(); 135 | 136 | template.sendBody("direct:camel-plantuml-generate-plantuml", null); 137 | MockEndpoint.assertIsSatisfied(context); 138 | } 139 | 140 | @Override 141 | protected RoutesBuilder createRouteBuilder() { 142 | return new RouteBuilder() { 143 | @Override 144 | public void configure() throws Exception { 145 | from(timer("foo").period(5000)).routeId("slowTimerRoute") 146 | .description("Route which generates slow periodic events") 147 | .setBody(constant("slow")) 148 | .to(seda("endpoint1")).id("_to01"); 149 | 150 | from(timer("bar").period(1000)).routeId("fastTimerRoute") 151 | .description("Route which generates fast periodic events") 152 | .setBody(constant("fast")) 153 | .to(seda("endpoint1")).id("_to02"); 154 | 155 | from(seda("endpoint1")).routeId("mainRoute").autoStartup(false) 156 | .description("Route which handles processing of the message") 157 | .log(LoggingLevel.INFO, "${body}") 158 | .enrich().constant("direct://endpoint2").id("_enrich01") 159 | .toD(mock("mock-${body}")).id("_toD01"); 160 | 161 | from(direct("endpoint2")).routeId("transformRoute") 162 | .description("Route which transforms the message") 163 | .transform(simple("${body}${body}")); 164 | 165 | getContext().addRoutes(new CamelPlantUmlRouteBuilder()); 166 | 167 | } 168 | 169 | }; 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/test/java/DefaultExample/DefaultExampleWithDuplicateProducerTest.java: -------------------------------------------------------------------------------- 1 | package DefaultExample; 2 | 3 | import io.github.ncasaux.camelplantuml.routebuilder.CamelPlantUmlRouteBuilder; 4 | import org.apache.camel.LoggingLevel; 5 | import org.apache.camel.RoutesBuilder; 6 | import org.apache.camel.builder.AdviceWith; 7 | import org.apache.camel.builder.RouteBuilder; 8 | import org.apache.camel.component.mock.MockEndpoint; 9 | import org.apache.camel.test.junit5.CamelTestSupport; 10 | import org.junit.jupiter.api.Test; 11 | 12 | import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.*; 13 | 14 | public class DefaultExampleWithDuplicateProducerTest extends CamelTestSupport { 15 | 16 | @Override 17 | public boolean isUseAdviceWith() { 18 | return true; 19 | } 20 | 21 | @Override 22 | public boolean useJmx() { 23 | return true; 24 | } 25 | 26 | @Test 27 | public void testMock() throws Exception { 28 | MockEndpoint mock = getMockEndpoint("mock:camel-plantuml-output"); 29 | 30 | 31 | mock.expectedBodiesReceived("@startuml\n" + 32 | "\n" + 33 | "skinparam ArrowColor #Black\n" + 34 | "\n" + 35 | "skinparam rectangle {\n" + 36 | " RoundCorner 20\n" + 37 | "}\n" + 38 | "\n" + 39 | "skinparam rectangle<> {\n" + 40 | " BorderColor #6C8EBF\n" + 41 | " BackgroundColor #DAE8FC\n" + 42 | "}\n" + 43 | "\n" + 44 | "skinparam queue<> {\n" + 45 | "}\n" + 46 | "\n" + 47 | "skinparam queue<> {\n" + 48 | " BorderColor #B85450\n" + 49 | " BackgroundColor #F8CECC\n" + 50 | "}\n" + 51 | "\n" + 52 | "skinparam queue<> {\n" + 53 | " BorderColor #82B366\n" + 54 | " BackgroundColor #D5E8D4\n" + 55 | "}\n" + 56 | "\n" + 57 | "footer Generated with camel-plantuml on %date(\"dd-MM-yyyy HH:mm\")\n" + 58 | "\n" + 59 | "' === Some useful settings for tweaking diagram layout ===\n" + 60 | "'left to right direction\n" + 61 | "'hide stereotype\n" + 62 | "'skinparam nodesep 50\n" + 63 | "'skinparam ranksep 50\n" + 64 | "'skinparam wrapWidth 250\n" + 65 | "\n" + 66 | "rectangle route_2ad9f14c90052cf9002f79d5f9fa54cb <> as \"\n" + 67 | "mainRoute\n" + 68 | "....\n" + 69 | "Route which handles processing of the message\n" + 70 | "\"\n" + 71 | "\n" + 72 | "rectangle route_a4212b7daeffab7a6859963fce8df0c1 <> as \"\n" + 73 | "fastTimerRoute\n" + 74 | "....\n" + 75 | "Route which generates fast periodic events\n" + 76 | "\"\n" + 77 | "\n" + 78 | "rectangle route_2c3a25b7f186d9a06118c863dc529551 <> as \"\n" + 79 | "transformRoute\n" + 80 | "....\n" + 81 | "Route which transforms the message\n" + 82 | "\"\n" + 83 | "\n" + 84 | "rectangle route_e75ae82e12c615feefaf77105cf18e63 <> as \"\n" + 85 | "slowTimerRoute\n" + 86 | "....\n" + 87 | "Route which generates slow periodic events\n" + 88 | "\"\n" + 89 | "\n" + 90 | "queue endpoint_9259e64c942ad21bc3beebab69d91941 <><> as \"\n" + 91 | "seda://endpoint1\n" + 92 | "\"\n" + 93 | "\n" + 94 | "queue endpoint_c1749b7ed34e5395932c33f971ca4151 <><> as \"\n" + 95 | "timer://foo\n" + 96 | "\"\n" + 97 | "\n" + 98 | "queue endpoint_497a674fd655c44f28111e246619dc57 <><> as \"\n" + 99 | "timer://bar\n" + 100 | "\"\n" + 101 | "\n" + 102 | "queue endpoint_766e5055e2b624afb926345d34208088 <><> as \"\n" + 103 | "direct://endpoint2\n" + 104 | "\"\n" + 105 | "\n" + 106 | "endpoint_497a674fd655c44f28111e246619dc57 --> route_a4212b7daeffab7a6859963fce8df0c1 : from\n" + 107 | "\n" + 108 | "endpoint_9259e64c942ad21bc3beebab69d91941 --> route_2ad9f14c90052cf9002f79d5f9fa54cb : from\n" + 109 | "\n" + 110 | "endpoint_c1749b7ed34e5395932c33f971ca4151 --> route_e75ae82e12c615feefaf77105cf18e63 : from\n" + 111 | "\n" + 112 | "endpoint_766e5055e2b624afb926345d34208088 --> route_2c3a25b7f186d9a06118c863dc529551 : from\n" + 113 | "\n" + 114 | "route_e75ae82e12c615feefaf77105cf18e63 --> endpoint_9259e64c942ad21bc3beebab69d91941 : to\n" + 115 | "\n" + 116 | "route_a4212b7daeffab7a6859963fce8df0c1 --> endpoint_9259e64c942ad21bc3beebab69d91941 : to\n" + 117 | "\n" + 118 | "queue dynamic_producer_endpoint_1846cdc72007895e6140e286368e7049 <><> as \"\n" + 119 | "mock://mock-${body}\n" + 120 | "\"\n" + 121 | "\n" + 122 | "route_2ad9f14c90052cf9002f79d5f9fa54cb --> dynamic_producer_endpoint_1846cdc72007895e6140e286368e7049 : toD\n" + 123 | "\n" + 124 | "route_2ad9f14c90052cf9002f79d5f9fa54cb --> endpoint_766e5055e2b624afb926345d34208088 : enrich\n" + 125 | "\n" + 126 | "@enduml\n"); 127 | 128 | AdviceWith.adviceWith(context, "camel-plantuml-http-trigger", a -> { 129 | a.weaveAddLast().transform(a.body().regexReplaceAll("\r", "")); 130 | a.weaveAddLast().to("mock:camel-plantuml-output"); 131 | } 132 | ); 133 | 134 | context.start(); 135 | 136 | template.sendBody("direct:camel-plantuml-generate-plantuml", null); 137 | MockEndpoint.assertIsSatisfied(context); 138 | } 139 | 140 | @Override 141 | protected RoutesBuilder createRouteBuilder() { 142 | return new RouteBuilder() { 143 | @Override 144 | public void configure() throws Exception { 145 | from(timer("foo").period(5000)).routeId("slowTimerRoute") 146 | .description("Route which generates slow periodic events") 147 | .setBody(constant("slow")) 148 | .to(seda("endpoint1")).id("_to01"); 149 | 150 | from(timer("bar").period(1000)).routeId("fastTimerRoute") 151 | .description("Route which generates fast periodic events") 152 | .setBody(constant("fast")) 153 | .to(seda("endpoint1")).id("_to02") 154 | .to(seda("endpoint1")).id("_to03"); 155 | 156 | from(seda("endpoint1")).routeId("mainRoute") 157 | .description("Route which handles processing of the message") 158 | .log(LoggingLevel.INFO, "${body}") 159 | .enrich().constant("direct://endpoint2").id("_enrich01") 160 | .toD(mock("mock-${body}")).id("_toD01"); 161 | 162 | from(direct("endpoint2")).routeId("transformRoute") 163 | .description("Route which transforms the message") 164 | .transform(simple("${body}${body}")); 165 | 166 | getContext().addRoutes(new CamelPlantUmlRouteBuilder()); 167 | 168 | } 169 | 170 | }; 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /camel-plantuml-jar/src/test/java/DefaultExample/DefaultExampleWithInvalidUriFilterPatternTest.java: -------------------------------------------------------------------------------- 1 | package DefaultExample; 2 | 3 | import io.github.ncasaux.camelplantuml.routebuilder.CamelPlantUmlRouteBuilder; 4 | import org.apache.camel.LoggingLevel; 5 | import org.apache.camel.RoutesBuilder; 6 | import org.apache.camel.builder.AdviceWith; 7 | import org.apache.camel.builder.RouteBuilder; 8 | import org.apache.camel.component.mock.MockEndpoint; 9 | import org.apache.camel.test.junit5.CamelTestSupport; 10 | import org.junit.jupiter.api.Test; 11 | 12 | import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.direct; 13 | import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.mock; 14 | import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.seda; 15 | import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.timer; 16 | 17 | public class DefaultExampleWithInvalidUriFilterPatternTest extends CamelTestSupport { 18 | 19 | @Override 20 | public boolean isUseAdviceWith() { 21 | return true; 22 | } 23 | 24 | @Override 25 | public boolean useJmx() { 26 | return true; 27 | } 28 | 29 | @Test 30 | public void testMock() throws Exception { 31 | MockEndpoint mock = getMockEndpoint("mock:camel-plantuml-output"); 32 | 33 | 34 | mock.expectedBodiesReceived("@startuml\n" + 35 | "\n" + 36 | "skinparam ArrowColor #Black\n" + 37 | "\n" + 38 | "skinparam rectangle {\n" + 39 | " RoundCorner 20\n" + 40 | "}\n" + 41 | "\n" + 42 | "skinparam rectangle<> {\n" + 43 | " BorderColor #6C8EBF\n" + 44 | " BackgroundColor #DAE8FC\n" + 45 | "}\n" + 46 | "\n" + 47 | "skinparam queue<> {\n" + 48 | "}\n" + 49 | "\n" + 50 | "skinparam queue<> {\n" + 51 | " BorderColor #B85450\n" + 52 | " BackgroundColor #F8CECC\n" + 53 | "}\n" + 54 | "\n" + 55 | "skinparam queue<> {\n" + 56 | " BorderColor #82B366\n" + 57 | " BackgroundColor #D5E8D4\n" + 58 | "}\n" + 59 | "\n" + 60 | "footer Generated with camel-plantuml on %date(\"dd-MM-yyyy HH:mm\")\n" + 61 | "\n" + 62 | "' === Some useful settings for tweaking diagram layout ===\n" + 63 | "'left to right direction\n" + 64 | "'hide stereotype\n" + 65 | "'skinparam nodesep 50\n" + 66 | "'skinparam ranksep 50\n" + 67 | "'skinparam wrapWidth 250\n" + 68 | "\n" + 69 | "rectangle route_2ad9f14c90052cf9002f79d5f9fa54cb <> as \"\n" + 70 | "mainRoute\n" + 71 | "....\n" + 72 | "Route which handles processing of the message\n" + 73 | "\"\n" + 74 | "\n" + 75 | "rectangle route_a4212b7daeffab7a6859963fce8df0c1 <> as \"\n" + 76 | "fastTimerRoute\n" + 77 | "....\n" + 78 | "Route which generates fast periodic events\n" + 79 | "\"\n" + 80 | "\n" + 81 | "rectangle route_2c3a25b7f186d9a06118c863dc529551 <> as \"\n" + 82 | "transformRoute\n" + 83 | "....\n" + 84 | "Route which transforms the message\n" + 85 | "\"\n" + 86 | "\n" + 87 | "rectangle route_e75ae82e12c615feefaf77105cf18e63 <> as \"\n" + 88 | "slowTimerRoute\n" + 89 | "....\n" + 90 | "Route which generates slow periodic events\n" + 91 | "\"\n" + 92 | "\n" + 93 | "queue endpoint_9259e64c942ad21bc3beebab69d91941 <><> as \"\n" + 94 | "seda://endpoint1\n" + 95 | "\"\n" + 96 | "\n" + 97 | "queue endpoint_c1749b7ed34e5395932c33f971ca4151 <><> as \"\n" + 98 | "timer://foo\n" + 99 | "\"\n" + 100 | "\n" + 101 | "queue endpoint_497a674fd655c44f28111e246619dc57 <><> as \"\n" + 102 | "timer://bar\n" + 103 | "\"\n" + 104 | "\n" + 105 | "queue endpoint_766e5055e2b624afb926345d34208088 <><> as \"\n" + 106 | "direct://endpoint2\n" + 107 | "\"\n" + 108 | "\n" + 109 | "endpoint_497a674fd655c44f28111e246619dc57 --> route_a4212b7daeffab7a6859963fce8df0c1 : from\n" + 110 | "\n" + 111 | "endpoint_9259e64c942ad21bc3beebab69d91941 --> route_2ad9f14c90052cf9002f79d5f9fa54cb : from\n" + 112 | "\n" + 113 | "endpoint_c1749b7ed34e5395932c33f971ca4151 --> route_e75ae82e12c615feefaf77105cf18e63 : from\n" + 114 | "\n" + 115 | "endpoint_766e5055e2b624afb926345d34208088 --> route_2c3a25b7f186d9a06118c863dc529551 : from\n" + 116 | "\n" + 117 | "route_e75ae82e12c615feefaf77105cf18e63 --> endpoint_9259e64c942ad21bc3beebab69d91941 : to\n" + 118 | "\n" + 119 | "route_a4212b7daeffab7a6859963fce8df0c1 --> endpoint_9259e64c942ad21bc3beebab69d91941 : to\n" + 120 | "\n" + 121 | "queue dynamic_producer_endpoint_1846cdc72007895e6140e286368e7049 <><> as \"\n" + 122 | "mock://mock-${body}\n" + 123 | "\"\n" + 124 | "\n" + 125 | "route_2ad9f14c90052cf9002f79d5f9fa54cb --> dynamic_producer_endpoint_1846cdc72007895e6140e286368e7049 : toD\n" + 126 | "\n" + 127 | "route_2ad9f14c90052cf9002f79d5f9fa54cb --> endpoint_766e5055e2b624afb926345d34208088 : enrich\n" + 128 | "\n" + 129 | "@enduml\n"); 130 | 131 | AdviceWith.adviceWith(context, "camel-plantuml-http-trigger", a -> { 132 | a.weaveAddLast().transform(a.body().regexReplaceAll("\r", "")); 133 | a.weaveAddLast().to("mock:camel-plantuml-output"); 134 | } 135 | ); 136 | 137 | context.start(); 138 | 139 | template.sendBodyAndHeader("direct:camel-plantuml-generate-plantuml", null, "uriFilterPattern","*.foo"); 140 | MockEndpoint.assertIsSatisfied(context); 141 | } 142 | 143 | @Override 144 | protected RoutesBuilder createRouteBuilder() { 145 | return new RouteBuilder() { 146 | @Override 147 | public void configure() throws Exception { 148 | from(timer("foo").period(5000)).routeId("slowTimerRoute") 149 | .description("Route which generates slow periodic events") 150 | .setBody(constant("slow")) 151 | .to(seda("endpoint1")).id("_to01"); 152 | 153 | from(timer("bar").period(1000)).routeId("fastTimerRoute") 154 | .description("Route which generates fast periodic events") 155 | .setBody(constant("fast")) 156 | .to(seda("endpoint1")).id("_to02"); 157 | 158 | from(seda("endpoint1")).routeId("mainRoute") 159 | .description("Route which handles processing of the message") 160 | .log(LoggingLevel.INFO, "${body}") 161 | .enrich().constant("direct://endpoint2").id("_enrich01") 162 | .toD(mock("mock-${body}")).id("_toD01"); 163 | 164 | from(direct("endpoint2")).routeId("transformRoute") 165 | .description("Route which transforms the message") 166 | .transform(simple("${body}${body}")); 167 | 168 | getContext().addRoutes(new CamelPlantUmlRouteBuilder()); 169 | 170 | } 171 | 172 | }; 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Overview 2 | camel-plantuml is a tool which helps to generate [PlantUML](https://plantuml.com/) activity diagrams which describe Apache [Camel](https://camel.apache.org/) routes, based on an actual **running** Camel context. 3 | 4 | It allows to have diagrams where you can see interactions between endpoints and routes. 5 | 6 | If you consider following routes: 7 | ``` 8 | from(timer("foo").period(5000)).id("slowTimerRoute") 9 | .description("Route which generates slow periodic events") 10 | .setBody(constant("slow")) 11 | .to(seda("endpoint1")); 12 | 13 | from(timer("bar").period(1000)).id("fastTimerRoute") 14 | .description("Route which generates fast periodic events") 15 | .setBody(constant("fast")) 16 | .to(seda("endpoint1")); 17 | 18 | from(seda("endpoint1")).id("mainRoute") 19 | .description("Route which handles processing of the message") 20 | .log(LoggingLevel.INFO, "${body}") 21 | .enrich().constant("direct://endpoint2") 22 | .toD(mock("mock-${body}")); 23 | 24 | from(direct("endpoint2")).id("transformRoute") 25 | .description("Route which transforms the message") 26 | .transform(simple("${body}${body}")); 27 | ``` 28 | It will allow you to generate these images: 29 | 30 | - with all endpoints: 31 | 32 | ![](images/example1.full.svg) 33 | 34 | - without the "internal" endpoints: 35 | 36 | ![](images/example1.light.svg) 37 | 38 | This tool is intended to be a software documentation tool, it is not intended to be a monitoring tool with real-time metrics or statistics. 39 | 40 | ## How it works 41 | This tool needs to have access to a running Camel context instance. 42 | It uses the Camel JMX MBeans (which are enabled by default in Camel), and particularly the ones related to routes and processors. Therefore, this tool does NOT work during design time or coding of the Camel routes. It requires an actual running Camel context. 43 | 44 | Following processors are handled: 45 | - SendProcessor (`to`) 46 | - SendDynamicProcessor (`toD`) 47 | - Enricher (`enrich`) 48 | - PollEnricher (`pollEnrich`) 49 | - WireTapProcessor (`wireTap`) 50 | - RecipientList (`recipientList`) 51 | 52 | It parses the processors to extract URI(s) information. 53 | If an expression is found, then, based on the language of the expression: 54 | 1. If the language is `constant`, it will consider it as a static endpoint (which could be used in other processors or routes). 55 | 2. If the language is `simple`, it will consider it as a dynamic endpoint (with no possible link with other processors or routes). 56 | 3. Otherwise, it will ignore the endpoint. 57 | 58 | The PlantUML code is exposed through a configurable HTTP endpoint, so it can be re-worked, and finally rendered as an image. 59 | 60 | ## Features 61 | This tool generates PlantUML diagrams with following features: 62 | - each route is rendered as a rectangle, with its id and description 63 | - each static endpoint base URI is rendered as a queue with a "static" layout. 64 | - each dynamic endpoint URI is rendered as a queue with a "dynamic" layout. 65 | - each consumer is rendered as a labelled arrow (`from` or `pollEnrich`) which connects an endpoint to a route. 66 | - each producer is rendered as a labelled arrow (`to`,`toD`,`enrich`,`wireTap` or `recipientList`) which connects a route to an endpoint. 67 | - it is possible to connect the routes to each other, if you don't want to display the "internal" endpoints on the diagram. Routes have to share a `direct` or `seda` endpoint. 68 | - it is possible to exclude endpoints and/or routes which match a customizable URI pattern. 69 | 70 | 71 | ## How to use ? 72 | This tool can be used in two different ways: 73 | - _**embedded**_ mode: the tool is embedded to your application (suggested mode). 74 | - _**remote**_ mode: the tool connects to your application through an unsecured JMX url. 75 | 76 | ### Option 1: _embedded_ mode 77 | In this mode, the tool is embedded within your project and connects directly to the MBean server of your application's JVM. 78 | The tool exposes the UML diagram directly from your application through a dedicated HTTP endpoint. 79 | 80 | #### 1. Add the dependency to your project: 81 | The jar is a OSGi bundle, hence it can be used with Apache ServiceMix/Apache Karaf. 82 | ``` 83 | 84 | io.github.ncasaux 85 | camel-plantuml-jar 86 | x.y.z 87 | 88 | ``` 89 | 90 | Based on the Apache Camel version you use, choose the correct version: 91 | 92 | | **Apache Camel version** | **camel-plantuml version** | 93 | |--------------------------|----------------------------| 94 | | <= 3.15 | 1.3.x | 95 | | \>= 3.16 and <= 3.19 | 1.4.x | 96 | | \>= 3.20 | 1.5.x | 97 | | \>= 4.0 | 1.6.x | 98 | | \>= 4.4 | \>=1.7.x | 99 | 100 | #### 2. Add the route builder to your Camel context: 101 | `getContext().addRoutes(new CamelPlantUmlRouteBuilder());` 102 | 103 | Default host is `localhost`, default port is `8090`, but you can overide them: 104 | 105 | `getContext().addRoutes(new CamelPlantUmlRouteBuilder("localhost", 8090));` 106 | 107 | #### 3. Start your Camel context, and open a browser: 108 | To have all the endpoints, go to: 109 | 110 | `http://localhost:8090/camel-plantuml/diagram.puml` 111 | 112 | To connect routes directly (and hide "internal" endpoints), add the following parameter: 113 | 114 | `http://localhost:8090/camel-plantuml/diagram.puml?connectRoutes=true` 115 | 116 | To hide endpoints and/or routes which match a URI pattern (`.*foo.*` in following example), add the following parameter: 117 | 118 | `http://localhost:8090/camel-plantuml/diagram.puml?uriFilterPattern=.*foo.*` 119 | 120 | ### Option 2: _remote_ mode 121 | In this mode, the tool connects remotely to the MBean server of your application's JVM. 122 | The tool exposes the UML diagram directly from its dedicated HTTP endpoint. 123 | The tool is packaged as a zip file. 124 | 125 | #### 1. Download the zip file: 126 | Download the latest release from [here](https://github.com/ncasaux/camel-plantuml/releases) 127 | 128 | Unzip it in the folder of your choice and go into this folder. 129 | 130 | #### 2. Enable JMX unsecure connection in your application 131 | Start **your application** with following parameters and port of your choice: 132 | ``` 133 | -Dcom.sun.management.jmxremote.authenticate=false 134 | -Dcom.sun.management.jmxremote.ssl=false 135 | -Dcom.sun.management.jmxremote.port={{JMX_PORT}} 136 | -Djava.rmi.server.hostname={{YOUR_APPLICATION_IP}} 137 | ``` 138 | 139 | #### 3. Connect the tool to your application 140 | Start locally the tool with parameter `jmxHost`: 141 | 142 | `java -DjmxHost={{YOUR_APPLICATION_IP}}:{{JMX_PORT}} -jar camel-plantuml-zip-x.y.z.jar` 143 | 144 | #### 4. Open a browser: 145 | To display all the endpoints, go to: 146 | 147 | `http://localhost:8090/camel-plantuml/diagram.puml` 148 | 149 | To connect routes directly (and hide "internal" endpoints), add the following parameter: 150 | 151 | `http://localhost:8090/camel-plantuml/diagram.puml?connectRoutes=true` 152 | 153 | To hide endpoints and/or routes which match a URI pattern (`.*foo.*` in following example), add the following parameter: 154 | 155 | `http://localhost:8090/camel-plantuml/diagram.puml?uriFilterPattern=.*foo.*` 156 | 157 | ## Rendering the PlantUML Code 158 | There are multiple options: 159 | - You can install PlantUML extension on your IDE, and graphviz on your computer to render locally (the best option). 160 | - You can use a web browser extension to directly render the code. There are extensions for Chrome and Firefox. 161 | - You can use the official PlantUML [webserver](http://www.plantuml.com/plantuml/uml "PlantUML webserver") and copy/paste the diagram. 162 | 163 | ## FAQ 164 | 1. What are the differences with the [Camel plugin for hawtio](http://hawtio.github.io/hawtio/plugins/camel/) ? 165 | 166 | The Camel plugin for hawtio has also a graphical representation of routes and route steps. 167 | However, there is no graphical connection between routes directly, as each route is drawn individually. 168 | So you can not know the routes/endpoints interconnections. 169 | That is the main purpose of this tool. 170 | 171 | 2. Why this tool can not expose directly the images of the diagrams, instead (or along with) the PlantUML code? 172 | 173 | This tool is based on [legacy PlantUML activity diagrams](https://plantuml.com/en/activity-diagram-legacy). 174 | To draw such diagrams, Graphviz is required, and unfortunately, there is no Java implementation of Graphviz... 175 | 176 | 3. So, why don't this tool use the [new PlantUML activity diagrams](https://plantuml.com/en/activity-diagram-beta), 177 | which do not require Graphviz anymore ? 178 | 179 | As far as I know, the new activity diagram is not intended to create connections between any two actions, 180 | and that's completely incompatible with diagrams this tool aims to create. 181 | 182 | ## Contributing 183 | Any suggestion, remark, or question? Feel free to create an issue and/or to contribute by forking and making pull requests! 184 | 185 | ## Releases notes 186 | ### v1.8.0 187 | - Added customizable endpoint exclusion - Thanks to [ahauschulte](https://github.com/ahauschulte) 188 | 189 | ### v1.7.0 190 | - Changed to latest LTS Camel version (4.4.1) 191 | - Updated dependencies 192 | 193 | ### v1.6.0 194 | - Changed to latest LTS Camel version (4.0.4) 195 | - Updated dependencies 196 | 197 | ### v1.5.0 198 | - Changed to latest LTS Camel version (3.20.3) 199 | 200 | ### v1.4.0 201 | - Changed to latest LTS Camel version (3.18.1) 202 | - Enforced route, producer and consumer filtering on the diagram based on endpointBaseUri 203 | - Updated dependencies 204 | 205 | ### v1.3.0 206 | - Deprecated support for Camel 2.X version 207 | - Renamed camel3-plantuml to camel-plantuml 208 | - Added unit tests 209 | - Removed irrelevant code 210 | - Updated dependencies 211 | - Changed to latest LTS Camel version (3.14.3) 212 | 213 | ### v1.2.1 214 | - Renamed groupId and packages to io.github.ncasaux 215 | - Changed to latest LTS Camel3 version (3.11) and latest Camel2 version (2.25.4) 216 | - Updated POM to be able to publish to Maven Central 217 | - Updated dependencies version 218 | - Removed unused dependencies 219 | ### v1.1.1 220 | - Fixed that internal endpoints must be with scheme `direct` or `seda` to connect routes when using parameter `connectRoutes=true` 221 | - Fixed zip maven assembly and updated maven plugins versions 222 | ### v1.1.0 223 | - Added a remote mode to use the tool, which allows connection to an existing JMX MBean server 224 | - Added some tips in the .puml generated file to help layout tweaking 225 | - Display labels of producer AND consumer on arrows when using parameter `connectRoutes=true` 226 | - Route without description are now shown as is. 227 | ### v1.0.0 228 | - Initial version 229 | -------------------------------------------------------------------------------- /images/example1.light.svg: -------------------------------------------------------------------------------- 1 | «route»mainRouteRoute which handles processing of the message«route»fastTimerRouteRoute which generates fast periodic events«route»transformRouteRoute which transforms the message«route»slowTimerRouteRoute which generates slow periodic events«endpoint»«static»timer://bar&period=1000«endpoint»«static»timer://foo&period=5000«endpoint»«dynamic»mock://mock-${body}fromfromto / fromto / fromtoDenrich / from -------------------------------------------------------------------------------- /images/example1.full.svg: -------------------------------------------------------------------------------- 1 | «route»mainRouteRoute which handles processing of the message«route»fastTimerRouteRoute which generates fast periodic events«route»transformRouteRoute which transforms the message«route»slowTimerRouteRoute which generates slow periodic events«endpoint»«static»seda://endpoint1«endpoint»«static»direct://endpoint2«endpoint»«static»timer://bar&period=1000«endpoint»«static»timer://foo&period=5000«endpoint»«dynamic»mock://mock-${body}fromfromfromfromtototoDenrich --------------------------------------------------------------------------------