This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch camel-4.4.x in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/camel-4.4.x by this push: new 3897de5f14e CAMEL-20763: camel-support Handle special characters in REST templates (#14145) 3897de5f14e is described below commit 3897de5f14ee96d430db0817305ce224a06178e1 Author: David Riseley <6659301+drise...@users.noreply.github.com> AuthorDate: Wed May 15 11:23:38 2024 +0100 CAMEL-20763: camel-support Handle special characters in REST templates (#14145) Ensure that any hypens or underscores in parameters in REST templates are removed before being parsed into a regular expression --- .../support/RestConsumerContextPathMatcher.java | 28 ++++++++++++++++++- .../RestConsumerContextPathMatcherTest.java | 31 ++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/core/camel-support/src/main/java/org/apache/camel/support/RestConsumerContextPathMatcher.java b/core/camel-support/src/main/java/org/apache/camel/support/RestConsumerContextPathMatcher.java index ba534ae8a44..1b5683c5854 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/RestConsumerContextPathMatcher.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/RestConsumerContextPathMatcher.java @@ -39,6 +39,7 @@ import java.util.stream.Collectors; */ public final class RestConsumerContextPathMatcher { + private static final Pattern CONSUMER_PATH_PARAMETER_PATTERN = Pattern.compile("([^{]*)(\\{.*?\\})([^{]*)"); private static final Map<String, Pattern> PATH_PATTERN = new ConcurrentHashMap<>(); private RestConsumerContextPathMatcher() { @@ -252,9 +253,14 @@ public final class RestConsumerContextPathMatcher { * @param consumerPath a consumer path */ public static void register(String consumerPath) { + // Remove hyphens and underscores from parameter names + // as these are not supported in regex named group names + String regex = prepareConsumerPathRegex(consumerPath); + // Convert URI template to a regex pattern - String regex = consumerPath + regex = regex .replace("/", "\\/") + .replace("-", "\\-") .replace("{", "(?<") .replace("}", ">[^\\/]+)"); @@ -409,4 +415,24 @@ public final class RestConsumerContextPathMatcher { return matcher.matches(); } + /** + * Removes any hyphens or underscores from parameter names to create valid java regex named group names + * + * @param consumerPath + * @return + */ + private static String prepareConsumerPathRegex(String consumerPath) { + Matcher m = CONSUMER_PATH_PARAMETER_PATTERN.matcher(consumerPath); + StringBuilder regexBuilder = new StringBuilder(); + while (m.find()) { + m.appendReplacement(regexBuilder, m.group(1) + m.group(2).replaceAll("[\\_\\-]", "") + m.group(3)); + } + // No matches so return the original path + if (regexBuilder.isEmpty()) { + return consumerPath; + } else { + return regexBuilder.toString(); + } + } + } diff --git a/core/camel-support/src/test/java/org/apache/camel/support/RestConsumerContextPathMatcherTest.java b/core/camel-support/src/test/java/org/apache/camel/support/RestConsumerContextPathMatcherTest.java index 067905951ab..44f82107369 100644 --- a/core/camel-support/src/test/java/org/apache/camel/support/RestConsumerContextPathMatcherTest.java +++ b/core/camel-support/src/test/java/org/apache/camel/support/RestConsumerContextPathMatcherTest.java @@ -18,9 +18,14 @@ package org.apache.camel.support; import java.util.ArrayList; import java.util.List; +import java.util.stream.Stream; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -81,6 +86,32 @@ public class RestConsumerContextPathMatcherTest { assertEquals(path.getConsumerPath(), "/camel/a/b/{c}"); } + @ParameterizedTest + @MethodSource + public void testRestConsumerContextPathMatcherTemplateParseSuccess(String consumerPath, String requestPath) { + + assertDoesNotThrow(() -> RestConsumerContextPathMatcher.register(consumerPath)); + + List<RestConsumerContextPathMatcher.ConsumerPath<MockConsumerPath>> consumerPaths = new ArrayList<>(); + consumerPaths.add(new MockConsumerPath("GET", consumerPath)); + + RestConsumerContextPathMatcher.ConsumerPath<?> path = RestConsumerContextPathMatcher.matchBestPath("GET", + requestPath, consumerPaths); + + assertEquals(consumerPath, path.getConsumerPath()); + } + + private static Stream<Arguments> testRestConsumerContextPathMatcherTemplateParseSuccess() { + return Stream.of( + Arguments.of("/camel/{myparamname1}", "/camel/param"), + Arguments.of("/camel/{myParamName1}", "/camel/param"), + Arguments.of("/camel/{my_param_name1}", "/camel/param"), + Arguments.of("/camel/{my-param-name1}", "/camel/param"), + Arguments.of("/camel/{my-param_name1}", "/camel/param"), + Arguments.of("/camel/{my-param_name1}/path-ab/{my-param_name2}", "/camel/param1/path-ab/param2"), + Arguments.of("/camel/{my-param_name1}/path-ab/{my-param_name2}/*", "/camel/param1/path-ab/param2/something")); + } + @Test public void testRestConsumerContextPathMatcherWithWildcard() { List<RestConsumerContextPathMatcher.ConsumerPath<MockConsumerPath>> consumerPaths = new ArrayList<>();