This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch camel-3.4.x in repository https://gitbox.apache.org/repos/asf/camel.git
commit 598c109c5ea4b3bd959ea7de20468e6d4753d0a7 Author: Claus Ibsen <[email protected]> AuthorDate: Mon Aug 24 18:48:25 2020 +0200 CAMEL-15455: EndpointDSL with toD should not encoding endpoint parameters as they should be parsable with simple language, which needs to resolve first, before uri is encoded by ToD. --- .../builder/endpoint/AbstractEndpointBuilder.java | 13 ++++-- .../builder/endpoint/SedaSimpleExpressionTest.java | 54 ++++++++++++++++++++++ .../java/org/apache/camel/util/URISupport.java | 42 +++++++++++++---- 3 files changed, 95 insertions(+), 14 deletions(-) diff --git a/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/AbstractEndpointBuilder.java b/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/AbstractEndpointBuilder.java index 90ffc0f..a23ade9 100644 --- a/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/AbstractEndpointBuilder.java +++ b/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/AbstractEndpointBuilder.java @@ -53,7 +53,7 @@ public class AbstractEndpointBuilder { Map<String, Object> remaining = new LinkedHashMap<>(); // we should not bind complex objects to registry as we create the endpoint via the properties as-is - NormalizedEndpointUri uri = computeUri(remaining, context, false); + NormalizedEndpointUri uri = computeUri(remaining, context, false, true); ExtendedCamelContext ecc = (ExtendedCamelContext) context; Endpoint endpoint = ecc.getEndpoint(uri, properties); if (endpoint == null) { @@ -70,10 +70,10 @@ public class AbstractEndpointBuilder { } public String getUri() { - return computeUri(new LinkedHashMap<>(), null, false).getUri(); + return computeUri(new LinkedHashMap<>(), null, false, true).getUri(); } - protected NormalizedUri computeUri(Map<String, Object> remaining, CamelContext camelContext, boolean bindToRegistry) { + protected NormalizedUri computeUri(Map<String, Object> remaining, CamelContext camelContext, boolean bindToRegistry, boolean encode) { NormalizedUri answer; // sort parameters so it can be regarded as normalized @@ -99,7 +99,8 @@ public class AbstractEndpointBuilder { answer = new NormalizedUri(targetScheme + "://" + targetPath); } else { try { - String query = URISupport.createQueryString(params); + // build query string from parameters + String query = URISupport.createQueryString(params, encode); answer = new NormalizedUri(targetScheme + "://" + targetPath + "?" + query); } catch (URISyntaxException e) { throw RuntimeCamelException.wrapRuntimeCamelException(e); @@ -158,7 +159,9 @@ public class AbstractEndpointBuilder { public Expression expr(CamelContext camelContext) { // need to bind complex properties so we can return an uri that includes these parameters too - NormalizedEndpointUri uri = computeUri(new LinkedHashMap<>(), camelContext, true); + // do not encode computed uri as we want to preserve simple expressions, as this is used + // by ToDynamic which builds the uri string un-encoded for simple language parser to be able to parse + NormalizedEndpointUri uri = computeUri(new LinkedHashMap<>(), camelContext, true, false); return SimpleBuilder.simple(uri.getUri()); } diff --git a/core/camel-endpointdsl/src/test/java/org/apache/camel/builder/endpoint/SedaSimpleExpressionTest.java b/core/camel-endpointdsl/src/test/java/org/apache/camel/builder/endpoint/SedaSimpleExpressionTest.java new file mode 100644 index 0000000..08fedb6 --- /dev/null +++ b/core/camel-endpointdsl/src/test/java/org/apache/camel/builder/endpoint/SedaSimpleExpressionTest.java @@ -0,0 +1,54 @@ +/* + * 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.builder.endpoint; + +import org.apache.camel.EndpointInject; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.test.junit5.CamelTestSupport; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertSame; + +public class SedaSimpleExpressionTest extends CamelTestSupport { + + @EndpointInject(value = "mock:result") + private MockEndpoint result; + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new EndpointRouteBuilder() { + @Override + public void configure() throws Exception { + from(direct("start")).toD(seda("foo").size("${header.mySize}")); + + from(seda("foo").size(5)).to(mock("result")); + } + }; + } + + @Test + public void test() throws Exception { + MockEndpoint resultEndpoint = getMockEndpoint("mock:result"); + resultEndpoint.expectedMessageCount(1); + + template.sendBodyAndHeader("direct:start", "Hello World", "mySize", 5); + + assertMockEndpointsSatisfied(); + assertSame(result, resultEndpoint); + } +} diff --git a/core/camel-util/src/main/java/org/apache/camel/util/URISupport.java b/core/camel-util/src/main/java/org/apache/camel/util/URISupport.java index e2a9ca0..55e2f7e 100644 --- a/core/camel-util/src/main/java/org/apache/camel/util/URISupport.java +++ b/core/camel-util/src/main/java/org/apache/camel/util/URISupport.java @@ -404,10 +404,25 @@ public final class URISupport { */ @SuppressWarnings("unchecked") public static String createQueryString(Map<String, Object> options) throws URISyntaxException { - return createQueryString(options.keySet(), options); + return createQueryString(options.keySet(), options, true); } - public static String createQueryString(Collection<String> sortedKeys, Map<String, Object> options) throws URISyntaxException { + /** + * Assembles a query from the given map. + * + * @param options the map with the options (eg key/value pairs) + * @param encode whether to URL encode the query string + * @return a query string with <tt>key1=value&key2=value2&...</tt>, or an empty string if there + * is no options. + * @throws URISyntaxException is thrown if uri has invalid syntax. + */ + @SuppressWarnings("unchecked") + public static String createQueryString(Map<String, Object> options, boolean encode) throws URISyntaxException { + return createQueryString(options.keySet(), options, encode); + } + + public static String createQueryString(Collection<String> sortedKeys, Map<String, Object> options, boolean encode) + throws URISyntaxException { try { if (options.size() > 0) { StringBuilder rc = new StringBuilder(); @@ -428,7 +443,7 @@ public final class URISupport { List<String> list = (List<String>)value; for (Iterator<String> it = list.iterator(); it.hasNext();) { String s = it.next(); - appendQueryStringParameter(key, s, rc); + appendQueryStringParameter(key, s, rc, encode); // append & separator if there is more in the list // to append if (it.hasNext()) { @@ -438,7 +453,7 @@ public final class URISupport { } else { // use the value as a String String s = value != null ? value.toString() : null; - appendQueryStringParameter(key, s, rc); + appendQueryStringParameter(key, s, rc, encode); } } return rc.toString(); @@ -452,8 +467,13 @@ public final class URISupport { } } - private static void appendQueryStringParameter(String key, String value, StringBuilder rc) throws UnsupportedEncodingException { - rc.append(URLEncoder.encode(key, CHARSET)); + private static void appendQueryStringParameter(String key, String value, StringBuilder rc, boolean encode) + throws UnsupportedEncodingException { + if (encode) { + rc.append(URLEncoder.encode(key, CHARSET)); + } else { + rc.append(key); + } if (value == null) { return; } @@ -466,7 +486,11 @@ public final class URISupport { String s = StringHelper.replaceAll(value, "%", "%25"); rc.append(s); } else { - rc.append(URLEncoder.encode(value, CHARSET)); + if (encode) { + rc.append(URLEncoder.encode(value, CHARSET)); + } else { + rc.append(value); + } } } @@ -600,7 +624,7 @@ public final class URISupport { keys.sort(null); // build uri object with sorted parameters - query = URISupport.createQueryString(keys, parameters); + query = URISupport.createQueryString(keys, parameters, true); return buildUri(scheme, path, query); } } @@ -647,7 +671,7 @@ public final class URISupport { List<String> keys = new ArrayList<>(parameters.keySet()); keys.sort(null); // rebuild query with sorted parameters - query = URISupport.createQueryString(keys, parameters); + query = URISupport.createQueryString(keys, parameters, true); } return buildUri(scheme, path, query);
