Repository: camel Updated Branches: refs/heads/parser2 df70bdd76 -> 85f0b99f7
Camel route coverage maven plugin polished code Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/85f0b99f Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/85f0b99f Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/85f0b99f Branch: refs/heads/parser2 Commit: 85f0b99f706f17dc3b7b633f4dfe236b0d69c164 Parents: df70bdd Author: Claus Ibsen <davscl...@apache.org> Authored: Thu Oct 12 19:09:39 2017 +0200 Committer: Claus Ibsen <davscl...@apache.org> Committed: Thu Oct 12 19:16:17 2017 +0200 ---------------------------------------------------------------------- .../parser/helper/RouteCoverageHelper.java | 115 ++++++++++++++++++ .../apache/camel/parser/model/CoverageData.java | 39 +++++++ .../apache/camel/maven/RouteCoverageMojo.java | 18 +-- .../camel/maven/helper/RouteCoverageHelper.java | 117 ------------------- 4 files changed, 163 insertions(+), 126 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/85f0b99f/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/helper/RouteCoverageHelper.java ---------------------------------------------------------------------- diff --git a/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/helper/RouteCoverageHelper.java b/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/helper/RouteCoverageHelper.java new file mode 100644 index 0000000..2bc4bf8 --- /dev/null +++ b/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/helper/RouteCoverageHelper.java @@ -0,0 +1,115 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.parser.helper; + +import java.io.File; +import java.io.FileInputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import org.apache.camel.catalog.CamelCatalog; +import org.apache.camel.catalog.DefaultCamelCatalog; +import org.apache.camel.parser.model.CoverageData; + +/** + * Helper to provide route coverage details. + */ +public final class RouteCoverageHelper { + + private RouteCoverageHelper() { + } + + public static List<CoverageData> parseDumpRouteCoverageByRouteId(String directory, String routeId) throws Exception { + List<CoverageData> answer = new ArrayList<>(); + + File[] files = new File(directory).listFiles(f -> f.getName().endsWith(".xml")); + if (files == null) { + return answer; + } + + CamelCatalog catalog = new DefaultCamelCatalog(true); + + for (File file : files) { + try (FileInputStream fis = new FileInputStream(file)) { + Document dom = XmlLineNumberParser.parseXml(fis); + NodeList routes = dom.getElementsByTagName("route"); + for (int i = 0; i < routes.getLength(); i++) { + Node route = routes.item(i); + String id = route.getAttributes().getNamedItem("id").getNodeValue(); + // must be the target route + if (routeId.equals(id)) { + // parse each route and build a Map<String, Integer> with the no of messages processed + // where String is the EIP name + AtomicInteger counter = new AtomicInteger(); + parseRouteData(catalog, route, answer, counter); + } + } + } + } + + return answer; + } + + private static void parseRouteData(CamelCatalog catalog, Node node, List<CoverageData> data, AtomicInteger counter) { + // must be a known EIP model + String key = node.getNodeName(); + boolean valid = catalog.findModelNames().contains(key); // skip route as we use from instead + if (!valid) { + return; + } + + // only calculate for elements within the route + if (!"route".equals(key)) { + Integer count = 0; + Node total = node.getAttributes().getNamedItem("exchangesTotal"); + if (total != null) { + count = Integer.valueOf(total.getNodeValue()); + } + CoverageData holder = data.size() > counter.get() ? data.get(counter.get()) : null; + if (holder != null && holder.getNode().equals(key)) { + count += holder.getCount(); + } + if (holder == null) { + // add new + data.add(counter.get(), new CoverageData(key, count)); + } else { + // replace existing + data.set(counter.get(), new CoverageData(key, count)); + } + // advance counter + counter.incrementAndGet(); + } + + // any children + NodeList children = node.getChildNodes(); + if (children != null) { + for (int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + if (child instanceof Element) { + parseRouteData(catalog, child, data, counter); + } + } + } + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/85f0b99f/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/model/CoverageData.java ---------------------------------------------------------------------- diff --git a/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/model/CoverageData.java b/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/model/CoverageData.java new file mode 100644 index 0000000..97eee37 --- /dev/null +++ b/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/model/CoverageData.java @@ -0,0 +1,39 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.parser.model; + +/** + * Represents coverage data of a given node in the Camel route. + */ +public class CoverageData { + + private final String node; + private final int count; + + public CoverageData(String node, int count) { + this.count = count; + this.node = node; + } + + public String getNode() { + return node; + } + + public int getCount() { + return count; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/85f0b99f/tooling/maven/camel-maven-plugin/src/main/java/org/apache/camel/maven/RouteCoverageMojo.java ---------------------------------------------------------------------- diff --git a/tooling/maven/camel-maven-plugin/src/main/java/org/apache/camel/maven/RouteCoverageMojo.java b/tooling/maven/camel-maven-plugin/src/main/java/org/apache/camel/maven/RouteCoverageMojo.java index 2fbfe7d..6f89638 100644 --- a/tooling/maven/camel-maven-plugin/src/main/java/org/apache/camel/maven/RouteCoverageMojo.java +++ b/tooling/maven/camel-maven-plugin/src/main/java/org/apache/camel/maven/RouteCoverageMojo.java @@ -30,12 +30,12 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; import org.apache.camel.maven.helper.EndpointHelper; -import org.apache.camel.maven.helper.RouteCoverageHelper; import org.apache.camel.maven.model.RouteCoverageNode; import org.apache.camel.parser.RouteBuilderParser; import org.apache.camel.parser.XmlRouteParser; +import org.apache.camel.parser.helper.RouteCoverageHelper; import org.apache.camel.parser.model.CamelNodeDetails; -import org.apache.camel.util.KeyValueHolder; +import org.apache.camel.parser.model.CoverageData; import org.apache.maven.model.Resource; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; @@ -181,7 +181,7 @@ public class RouteCoverageMojo extends AbstractExecMojo { // grab dump data for the route try { - List<KeyValueHolder<String, Integer>> coverageData = RouteCoverageHelper.parseDumpRouteCoverageByRouteId("target/camel-route-coverage", routeId); + List<CoverageData> coverageData = RouteCoverageHelper.parseDumpRouteCoverageByRouteId("target/camel-route-coverage", routeId); if (coverageData.isEmpty()) { getLog().warn("No route coverage data found for route: " + routeId + ". Make sure to enable route coverage in your unit tests and assign unique route ids to your routes. Also remember to run unit tests first."); @@ -241,17 +241,17 @@ public class RouteCoverageMojo extends AbstractExecMojo { return bos.toString(); } - private static List<RouteCoverageNode> gatherRouteCoverageSummary(CamelNodeDetails route, List<KeyValueHolder<String, Integer>> coverageData) { + private static List<RouteCoverageNode> gatherRouteCoverageSummary(CamelNodeDetails route, List<CoverageData> coverageData) { List<RouteCoverageNode> answer = new ArrayList<>(); - Iterator<KeyValueHolder<String, Integer>> it = coverageData.iterator(); + Iterator<CoverageData> it = coverageData.iterator(); AtomicInteger level = new AtomicInteger(); gatherRouteCoverageSummary(route, it, level, answer); return answer; } - private static void gatherRouteCoverageSummary(CamelNodeDetails node, Iterator<KeyValueHolder<String, Integer>> it, AtomicInteger level, List<RouteCoverageNode> answer) { + private static void gatherRouteCoverageSummary(CamelNodeDetails node, Iterator<CoverageData> it, AtomicInteger level, List<RouteCoverageNode> answer) { RouteCoverageNode data = new RouteCoverageNode(); data.setName(node.getName()); data.setLineNumber(Integer.valueOf(node.getLineNumber())); @@ -265,10 +265,10 @@ public class RouteCoverageMojo extends AbstractExecMojo { // find count boolean found = false; while (!found && it.hasNext()) { - KeyValueHolder<String, Integer> holder = it.next(); - found = holder.getKey().equals(node.getName()); + CoverageData holder = it.next(); + found = holder.getNode().equals(node.getName()); if (found) { - data.setCount(holder.getValue()); + data.setCount(holder.getCount()); } } http://git-wip-us.apache.org/repos/asf/camel/blob/85f0b99f/tooling/maven/camel-maven-plugin/src/main/java/org/apache/camel/maven/helper/RouteCoverageHelper.java ---------------------------------------------------------------------- diff --git a/tooling/maven/camel-maven-plugin/src/main/java/org/apache/camel/maven/helper/RouteCoverageHelper.java b/tooling/maven/camel-maven-plugin/src/main/java/org/apache/camel/maven/helper/RouteCoverageHelper.java deleted file mode 100644 index 7e1a8ae..0000000 --- a/tooling/maven/camel-maven-plugin/src/main/java/org/apache/camel/maven/helper/RouteCoverageHelper.java +++ /dev/null @@ -1,117 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.camel.maven.helper; - -import java.io.File; -import java.io.FileInputStream; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import org.apache.camel.catalog.CamelCatalog; -import org.apache.camel.catalog.DefaultCamelCatalog; -import org.apache.camel.util.IOHelper; -import org.apache.camel.util.KeyValueHolder; -import org.apache.camel.util.XmlLineNumberParser; - -public final class RouteCoverageHelper { - - private RouteCoverageHelper() { - } - - // TODO: improve this api what is returned - // TODO: move this to camel-route-parser - - public static List<KeyValueHolder<String, Integer>> parseDumpRouteCoverageByRouteId(String directory, String routeId) throws Exception { - List<KeyValueHolder<String, Integer>> answer = new ArrayList<>(); - - File[] files = new File(directory).listFiles(f -> f.getName().endsWith(".xml")); - if (files == null) { - return answer; - } - - CamelCatalog catalog = new DefaultCamelCatalog(true); - - for (File file : files) { - FileInputStream fis = new FileInputStream(file); - Document dom = XmlLineNumberParser.parseXml(fis); - IOHelper.close(fis); - NodeList routes = dom.getElementsByTagName("route"); - for (int i = 0; i < routes.getLength(); i++) { - Node route = routes.item(i); - String id = route.getAttributes().getNamedItem("id").getNodeValue(); - // must be the target route - if (routeId.equals(id)) { - // parse each route and build a Map<String, Integer> with the no of messages processed - // where String is the EIP name - AtomicInteger counter = new AtomicInteger(); - parseRouteData(catalog, route, answer, counter); - } - } - } - - return answer; - } - - private static void parseRouteData(CamelCatalog catalog, Node node, List<KeyValueHolder<String, Integer>> data, AtomicInteger counter) { - // must be a known EIP model - String key = node.getNodeName(); - boolean valid = catalog.findModelNames().contains(key); // skip route as we use from instead - if (!valid) { - return; - } - - // only calculate for elements within the route - if (!"route".equals(key)) { - Integer count = 0; - Node total = node.getAttributes().getNamedItem("exchangesTotal"); - if (total != null) { - count = Integer.valueOf(total.getNodeValue()); - } - KeyValueHolder<String, Integer> holder = data.size() > counter.get() ? data.get(counter.get()) : null; - if (holder != null && holder.getKey().equals(key)) { - count += holder.getValue(); - } - if (holder == null) { - // add new - data.add(counter.get(), new KeyValueHolder<>(key, count)); - } else { - // replace existing - data.set(counter.get(), new KeyValueHolder<>(key, count)); - } - // advance counter - counter.incrementAndGet(); - } - - // any children - NodeList children = node.getChildNodes(); - if (children != null) { - for (int i = 0; i < children.getLength(); i++) { - Node child = children.item(i); - if (child instanceof Element) { - parseRouteData(catalog, child, data, counter); - } - } - } - } - -}