CAMEL-10344: RouteIdFactory for rest routes
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/b0025751 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/b0025751 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/b0025751 Branch: refs/heads/master Commit: b0025751386f59e7020ebd5cc19b9580eb477f46 Parents: 0da9713 Author: Tomasz Kopczynski <to...@kopczynski.net.pl> Authored: Sun Nov 27 20:05:49 2016 +0100 Committer: Claus Ibsen <davscl...@apache.org> Committed: Thu Dec 1 12:23:22 2016 +0100 ---------------------------------------------------------------------- .../org/apache/camel/impl/RouteIdFactory.java | 126 ++++++++++++++++--- .../apache/camel/model/rest/RestDefinition.java | 8 +- .../apache/camel/model/rest/VerbDefinition.java | 10 +- .../apache/camel/impl/RouteIdFactoryTest.java | 15 +++ 4 files changed, 143 insertions(+), 16 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/b0025751/camel-core/src/main/java/org/apache/camel/impl/RouteIdFactory.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/impl/RouteIdFactory.java b/camel-core/src/main/java/org/apache/camel/impl/RouteIdFactory.java index 5fdb51c..06044ea 100644 --- a/camel-core/src/main/java/org/apache/camel/impl/RouteIdFactory.java +++ b/camel-core/src/main/java/org/apache/camel/impl/RouteIdFactory.java @@ -22,20 +22,22 @@ import java.util.Optional; import org.apache.camel.NamedNode; import org.apache.camel.model.FromDefinition; import org.apache.camel.model.RouteDefinition; -import org.apache.camel.model.rest.RestBindingDefinition; +import org.apache.camel.model.rest.RestDefinition; +import org.apache.camel.model.rest.VerbDefinition; import org.apache.camel.spi.NodeIdFactory; /** * Factory for generating route ids based on uris. * <p> * For direct/seda routes it returns route name (direct:start -> start). - * For rest routes it returns its context path. + * For rest routes it returns its method and context path formatted as one string. * <p> * When id cannot be generated, falls back to other {@link NodeIdFactory} implementation. * If none is passed in the constructor, then {@link DefaultNodeIdFactory} is used. */ public class RouteIdFactory implements NodeIdFactory { + private static final char SEPARATOR = '-'; private NodeIdFactory defaultNodeIdFactory; public RouteIdFactory() { @@ -62,6 +64,14 @@ public class RouteIdFactory implements NodeIdFactory { } } + if (definition instanceof VerbDefinition) { + Optional<String> id = extractIdFromVerb((VerbDefinition) definition); + + if (id.isPresent()) { + return id.get(); + } + } + return defaultNodeIdFactory.createId(definition); } @@ -69,6 +79,10 @@ public class RouteIdFactory implements NodeIdFactory { * Extract id from routes */ private Optional<String> extractId(RouteDefinition routeDefinition) { + if (routeDefinition.getRestDefinition() != null) { + return Optional.empty(); + } + List<FromDefinition> inputs = routeDefinition.getInputs(); if (inputs == null || inputs.isEmpty()) { @@ -97,27 +111,111 @@ public class RouteIdFactory implements NodeIdFactory { } /** - * Extract id from rest route. + * Extract id from a rest route. */ private Optional<String> extractIdFromRestDefinition(RouteDefinition route) { - if (route.getOutputs().get(0) instanceof RestBindingDefinition) { - if (route.getRestDefinition() == null) { - return Optional.empty(); - } + if (route.getRestDefinition() != null) { + return extractIdFromInput(route); + } - String path = route.getRestDefinition().getPath(); + return Optional.empty(); + } - if (path == null) { - return Optional.empty(); - } + /** + * Extract id from a rest verb definition. + */ + private Optional<String> extractIdFromVerb(VerbDefinition verb) { + RestDefinition restDefinition = verb.getRest(); + + if (restDefinition != null) { + StringBuilder routeId = new StringBuilder(); + routeId.append(verb.asVerb()); + appendWithSeparator(routeId, prepareUri(restDefinition.getPath())); - if (path.indexOf('/') > 0) { - return Optional.of(path.substring(0, path.indexOf('/'))); + if (verb.getUri() != null && verb.getUri().length() > 0) { + appendWithSeparator(routeId, prepareUri(verb.getUri())); } - return Optional.of(path); + verb.setUsedForGeneratingNodeId(true); + + return Optional.of(routeId.toString()); } return Optional.empty(); + + } + + /** + * Extract id from rest input uri. + */ + private Optional<String> extractIdFromInput(RouteDefinition route) { + List<FromDefinition> inputs = route.getInputs(); + + if (inputs == null || inputs.isEmpty()) { + return Optional.empty(); + } + + FromDefinition from = inputs.get(0); + String uri = from.getUri(); + + String[] uriSplitted = uri.split(":"); + + // needs to have at least 3 fields + if (uriSplitted.length < 3) { + return Optional.empty(); + } + + String verb = uriSplitted[1]; + String contextPath = uriSplitted[2]; + String additionalUri = ""; + + if (uriSplitted.length > 3 && uriSplitted[3].startsWith("/")) { + additionalUri = uriSplitted[3]; + } + + StringBuilder routeId = new StringBuilder(verb.length() + contextPath.length() + additionalUri.length()); + + routeId.append(verb); + appendWithSeparator(routeId, prepareUri(contextPath)); + + if (additionalUri.length() > 0) { + appendWithSeparator(routeId, prepareUri(additionalUri)); + } + + return Optional.of(routeId.toString()); + } + + /** + * Prepares uri to be part of the id. + */ + private String prepareUri(String uri) { + if (uri == null) { + return ""; + } + + if (uri.contains("?")) { + uri = uri.substring(0, uri.indexOf('?')); + } + + return uri.replaceAll("/", String.valueOf(SEPARATOR)); + } + + /** + * Appends new element to the builder. + */ + private void appendWithSeparator(StringBuilder builder, String str) { + if (builder.charAt(builder.length() - 1) == SEPARATOR) { + if (str.startsWith(String.valueOf(SEPARATOR))) { + builder.append(str.replaceFirst(String.valueOf(SEPARATOR), "")); + } else { + builder.append(str); + } + } else { + if (!str.startsWith(String.valueOf(SEPARATOR))) { + builder.append(SEPARATOR); + } + + builder.append(str); + } } } http://git-wip-us.apache.org/repos/asf/camel/blob/b0025751/camel-core/src/main/java/org/apache/camel/model/rest/RestDefinition.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/model/rest/RestDefinition.java b/camel-core/src/main/java/org/apache/camel/model/rest/RestDefinition.java index c7ba4b8..68deb66 100644 --- a/camel-core/src/main/java/org/apache/camel/model/rest/RestDefinition.java +++ b/camel-core/src/main/java/org/apache/camel/model/rest/RestDefinition.java @@ -772,7 +772,13 @@ public class RestDefinition extends OptionalIdentifiedDefinition<RestDefinition> route.setId(id); } } - String routeId = route.idOrCreate(camelContext.getNodeIdFactory()); + + String routeId = verb.idOrCreate(camelContext.getNodeIdFactory()); + + if (!verb.getUsedForGeneratingNodeId()) { + routeId = route.idOrCreate(camelContext.getNodeIdFactory()); + } + verb.setRouteId(routeId); options.put("routeId", routeId); if (component != null && !component.isEmpty()) { http://git-wip-us.apache.org/repos/asf/camel/blob/b0025751/camel-core/src/main/java/org/apache/camel/model/rest/VerbDefinition.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/model/rest/VerbDefinition.java b/camel-core/src/main/java/org/apache/camel/model/rest/VerbDefinition.java index be27799..cc6731e 100644 --- a/camel-core/src/main/java/org/apache/camel/model/rest/VerbDefinition.java +++ b/camel-core/src/main/java/org/apache/camel/model/rest/VerbDefinition.java @@ -101,6 +101,9 @@ public class VerbDefinition extends OptionalIdentifiedDefinition<VerbDefinition> @XmlAttribute private Boolean apiDocs; + @XmlTransient + private Boolean usedForGeneratingNodeId = Boolean.FALSE; + @Override public String getLabel() { if (method != null) { @@ -406,6 +409,11 @@ public class VerbDefinition extends OptionalIdentifiedDefinition<VerbDefinition> } } + public Boolean getUsedForGeneratingNodeId() { + return usedForGeneratingNodeId; + } - + public void setUsedForGeneratingNodeId(Boolean usedForGeneratingNodeId) { + this.usedForGeneratingNodeId = usedForGeneratingNodeId; + } } http://git-wip-us.apache.org/repos/asf/camel/blob/b0025751/camel-core/src/test/java/org/apache/camel/impl/RouteIdFactoryTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/impl/RouteIdFactoryTest.java b/camel-core/src/test/java/org/apache/camel/impl/RouteIdFactoryTest.java index d6ecb71..c74ea06 100644 --- a/camel-core/src/test/java/org/apache/camel/impl/RouteIdFactoryTest.java +++ b/camel-core/src/test/java/org/apache/camel/impl/RouteIdFactoryTest.java @@ -39,6 +39,9 @@ public class RouteIdFactoryTest extends ContextTestSupport { context.setNodeIdFactory(new RouteIdFactory()); from("direct:start1?timeout=30000").to("mock:result"); from("direct:start2").to("mock:result"); + rest("/say/hello").get("/bar").to("mock:result"); + rest("/say/hello").get().to("mock:result"); + rest().get("/hello").to("mock:result"); } }; } @@ -51,4 +54,16 @@ public class RouteIdFactoryTest extends ContextTestSupport { assertEquals("start2", context.getRouteDefinitions().get(1).getId()); } + public void testRestRouteIdWithVerbUri() { + assertEquals("get-say-hello-bar", context.getRouteDefinitions().get(2).getId()); + } + + public void testRestRouteIdWithoutVerbUri() { + assertEquals("get-say-hello", context.getRouteDefinitions().get(3).getId()); + } + + public void testRestRouteIdWithoutPathUri() { + assertEquals("get-hello", context.getRouteDefinitions().get(4).getId()); + } + } \ No newline at end of file