CAMEL-8996: undertow support query params in producer
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/47f79a65 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/47f79a65 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/47f79a65 Branch: refs/heads/master Commit: 47f79a65ea20a40c80b3502d8c766f1f72c3e3e8 Parents: cdd64e1 Author: Claus Ibsen <davscl...@apache.org> Authored: Fri Jul 24 09:33:04 2015 +0200 Committer: Claus Ibsen <davscl...@apache.org> Committed: Fri Jul 24 09:33:04 2015 +0200 ---------------------------------------------------------------------- .../undertow/DefaultUndertowHttpBinding.java | 10 +- .../component/undertow/UndertowComponent.java | 21 ++- .../component/undertow/UndertowEndpoint.java | 9 +- .../component/undertow/UndertowHelper.java | 127 +++++++++++++++++++ .../component/undertow/UndertowProducer.java | 11 +- .../camel/component/undertow/UndertowUtils.java | 47 ------- .../undertow/UndertowProducerTest.java | 11 ++ 7 files changed, 176 insertions(+), 60 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/47f79a65/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/DefaultUndertowHttpBinding.java ---------------------------------------------------------------------- diff --git a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/DefaultUndertowHttpBinding.java b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/DefaultUndertowHttpBinding.java index e1d6c7e..e19d46d 100644 --- a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/DefaultUndertowHttpBinding.java +++ b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/DefaultUndertowHttpBinding.java @@ -137,7 +137,7 @@ public class DefaultUndertowHttpBinding implements UndertowHttpBinding { if (value != null && value.trim().startsWith("Basic")) { if (headerFilterStrategy != null && !headerFilterStrategy.applyFilterToExternalHeaders(Exchange.AUTHENTICATION, "Basic", exchange)) { - UndertowUtils.appendHeader(headersMap, Exchange.AUTHENTICATION, "Basic"); + UndertowHelper.appendHeader(headersMap, Exchange.AUTHENTICATION, "Basic"); } } } @@ -149,7 +149,7 @@ public class DefaultUndertowHttpBinding implements UndertowHttpBinding { LOG.trace("HTTP-header: {}", value); if (headerFilterStrategy != null && !headerFilterStrategy.applyFilterToExternalHeaders(name.toString(), value, exchange)) { - UndertowUtils.appendHeader(headersMap, name.toString(), value); + UndertowHelper.appendHeader(headersMap, name.toString(), value); } } } @@ -168,7 +168,7 @@ public class DefaultUndertowHttpBinding implements UndertowHttpBinding { LOG.trace("URI-Parameter: {}", value); if (headerFilterStrategy != null && !headerFilterStrategy.applyFilterToExternalHeaders(name, value, exchange)) { - UndertowUtils.appendHeader(headersMap, name, value); + UndertowHelper.appendHeader(headersMap, name, value); } } } @@ -194,7 +194,7 @@ public class DefaultUndertowHttpBinding implements UndertowHttpBinding { if (value != null && value.trim().startsWith("Basic")) { if (headerFilterStrategy != null && !headerFilterStrategy.applyFilterToExternalHeaders(Exchange.AUTHENTICATION, "Basic", exchange)) { - UndertowUtils.appendHeader(headersMap, Exchange.AUTHENTICATION, "Basic"); + UndertowHelper.appendHeader(headersMap, Exchange.AUTHENTICATION, "Basic"); } } } @@ -206,7 +206,7 @@ public class DefaultUndertowHttpBinding implements UndertowHttpBinding { LOG.trace("HTTP-header: {}", value); if (headerFilterStrategy != null && !headerFilterStrategy.applyFilterToExternalHeaders(name.toString(), value, exchange)) { - UndertowUtils.appendHeader(headersMap, name.toString(), value); + UndertowHelper.appendHeader(headersMap, name.toString(), value); } } } http://git-wip-us.apache.org/repos/asf/camel/blob/47f79a65/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowComponent.java ---------------------------------------------------------------------- diff --git a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowComponent.java b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowComponent.java index d037eae..84676b8 100644 --- a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowComponent.java +++ b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowComponent.java @@ -53,13 +53,26 @@ public class UndertowComponent extends UriEndpointComponent implements RestConsu @Override protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception { - String address = remaining; - URI httpUri = new URI(UnsafeUriCharactersEncoder.encodeHttpURI(address)); - URI endpointUri = URISupport.createRemainingURI(httpUri, parameters); + URI uriHttpUriAddress = new URI(UnsafeUriCharactersEncoder.encodeHttpURI(remaining)); + URI endpointUri = URISupport.createRemainingURI(uriHttpUriAddress, parameters); - UndertowEndpoint endpoint = new UndertowEndpoint(endpointUri.toString(), this, httpUri); + // create the endpoint first + UndertowEndpoint endpoint = new UndertowEndpoint(endpointUri.toString(), this); endpoint.setUndertowHttpBinding(undertowHttpBinding); setProperties(endpoint, parameters); + + // then re-create the http uri with the remaining parameters which the endpoint did not use + URI httpUri = URISupport.createRemainingURI( + new URI(uriHttpUriAddress.getScheme(), + uriHttpUriAddress.getUserInfo(), + uriHttpUriAddress.getHost(), + uriHttpUriAddress.getPort(), + uriHttpUriAddress.getPath(), + uriHttpUriAddress.getQuery(), + uriHttpUriAddress.getFragment()), + parameters); + endpoint.setHttpURI(httpUri); + return endpoint; } http://git-wip-us.apache.org/repos/asf/camel/blob/47f79a65/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowEndpoint.java ---------------------------------------------------------------------- diff --git a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowEndpoint.java b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowEndpoint.java index 1c25225..71899ca 100644 --- a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowEndpoint.java +++ b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowEndpoint.java @@ -65,10 +65,9 @@ public class UndertowEndpoint extends DefaultEndpoint implements HeaderFilterStr @UriParam private Boolean transferException; - public UndertowEndpoint(String uri, UndertowComponent component, URI httpURI) throws URISyntaxException { + public UndertowEndpoint(String uri, UndertowComponent component) throws URISyntaxException { super(uri, component); this.component = component; - this.httpURI = httpURI; } @Override @@ -97,6 +96,12 @@ public class UndertowEndpoint extends DefaultEndpoint implements HeaderFilterStr return true; } + @Override + public boolean isLenientProperties() { + // true to allow dynamic URI options to be configured and passed to external system for eg. the UndertowProducer + return true; + } + public Exchange createExchange(HttpServerExchange httpExchange) throws Exception { Exchange exchange = createExchange(); http://git-wip-us.apache.org/repos/asf/camel/blob/47f79a65/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowHelper.java ---------------------------------------------------------------------- diff --git a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowHelper.java b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowHelper.java new file mode 100644 index 0000000..8b55ccc --- /dev/null +++ b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowHelper.java @@ -0,0 +1,127 @@ +/** + * 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.component.undertow; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.camel.Exchange; +import org.apache.camel.RuntimeExchangeException; +import org.apache.camel.util.URISupport; +import org.apache.camel.util.UnsafeUriCharactersEncoder; + +/** + * Helper class for useful methods used all over the component + */ +public final class UndertowHelper { + + private UndertowHelper() { + } + + /** + * Creates the URL to invoke. + * + * @param exchange the exchange + * @param endpoint the endpoint + * @return the URL to invoke + */ + public static String createURL(Exchange exchange, UndertowEndpoint endpoint) { + String uri = null; +// if (!(endpoint.isBridgeEndpoint())) { +// uri = exchange.getIn().getHeader(Exchange.HTTP_URI, String.class); +// } + if (uri == null) { + uri = endpoint.getHttpURI().toASCIIString(); + } + + // resolve placeholders in uri + try { + uri = exchange.getContext().resolvePropertyPlaceholders(uri); + } catch (Exception e) { + throw new RuntimeExchangeException("Cannot resolve property placeholders with uri: " + uri, exchange, e); + } + + // append HTTP_PATH to HTTP_URI if it is provided in the header + String path = exchange.getIn().getHeader(Exchange.HTTP_PATH, String.class); + // NOW the HTTP_PATH is just related path, we don't need to trim it + if (path != null) { + if (path.startsWith("/")) { + path = path.substring(1); + } + if (path.length() > 0) { + // make sure that there is exactly one "/" between HTTP_URI and + // HTTP_PATH + if (!uri.endsWith("/")) { + uri = uri + "/"; + } + uri = uri.concat(path); + } + } + + // ensure uri is encoded to be valid + uri = UnsafeUriCharactersEncoder.encodeHttpURI(uri); + + return uri; + } + + /** + * Creates the URI to invoke. + * + * @param exchange the exchange + * @param url the url to invoke + * @param endpoint the endpoint + * @return the URI to invoke + */ + public static URI createURI(Exchange exchange, String url, UndertowEndpoint endpoint) throws URISyntaxException { + URI uri = new URI(url); + // is a query string provided in the endpoint URI or in a header (header overrules endpoint) + String queryString = exchange.getIn().getHeader(Exchange.HTTP_QUERY, String.class); + if (queryString == null) { + queryString = endpoint.getHttpURI().getRawQuery(); + } + // We should user the query string from the HTTP_URI header + if (queryString == null) { + queryString = uri.getRawQuery(); + } + if (queryString != null) { + // need to encode query string + queryString = UnsafeUriCharactersEncoder.encodeHttpURI(queryString); + uri = URISupport.createURIWithQuery(uri, queryString); + } + return uri; + } + + public static void appendHeader(Map<String, Object> headers, String key, Object value) { + if (headers.containsKey(key)) { + Object existing = headers.get(key); + List<Object> list; + if (existing instanceof List) { + list = (List<Object>) existing; + } else { + list = new ArrayList<Object>(); + list.add(existing); + } + list.add(value); + value = list; + } + + headers.put(key, value); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/47f79a65/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowProducer.java ---------------------------------------------------------------------- diff --git a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowProducer.java b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowProducer.java index fac4d8d..3f39e87 100644 --- a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowProducer.java +++ b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowProducer.java @@ -17,6 +17,7 @@ package org.apache.camel.component.undertow; import java.io.IOException; +import java.net.URI; import java.nio.ByteBuffer; import io.undertow.client.ClientCallback; @@ -71,9 +72,15 @@ public class UndertowProducer extends DefaultAsyncProducer { IoFuture<ClientConnection> connect = client.connect(endpoint.getHttpURI(), worker, new ByteBufferSlicePool(BufferAllocator.DIRECT_BYTE_BUFFER_ALLOCATOR, 8192, 8192 * 8192), OptionMap.EMPTY); + // creating the url to use takes 2-steps + String url = UndertowHelper.createURL(exchange, getEndpoint()); + URI uri = UndertowHelper.createURI(exchange, url, getEndpoint()); + // get the url from the uri + url = uri.toASCIIString(); + ClientRequest request = new ClientRequest(); request.setProtocol(Protocols.HTTP_1_1); - request.setPath(endpoint.getHttpURI().getPath()); + request.setPath(url); Object body = getRequestBody(request, exchange); @@ -86,7 +93,7 @@ public class UndertowProducer extends DefaultAsyncProducer { connect.get().sendRequest(request, new UndertowProducerCallback(bodyAsByte, exchange, callback)); - } catch (IOException e) { + } catch (Exception e) { exchange.setException(e); callback.done(true); return true; http://git-wip-us.apache.org/repos/asf/camel/blob/47f79a65/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowUtils.java ---------------------------------------------------------------------- diff --git a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowUtils.java b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowUtils.java deleted file mode 100644 index 43f2631..0000000 --- a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowUtils.java +++ /dev/null @@ -1,47 +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.component.undertow; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** - * Util class for useful methods used all over the component - */ -public final class UndertowUtils { - - private UndertowUtils() { - } - - public static void appendHeader(Map<String, Object> headers, String key, Object value) { - if (headers.containsKey(key)) { - Object existing = headers.get(key); - List<Object> list; - if (existing instanceof List) { - list = (List<Object>) existing; - } else { - list = new ArrayList<Object>(); - list.add(existing); - } - list.add(value); - value = list; - } - - headers.put(key, value); - } -} http://git-wip-us.apache.org/repos/asf/camel/blob/47f79a65/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowProducerTest.java ---------------------------------------------------------------------- diff --git a/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowProducerTest.java b/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowProducerTest.java index bda4767..ce24653 100644 --- a/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowProducerTest.java +++ b/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowProducerTest.java @@ -33,6 +33,17 @@ public class UndertowProducerTest extends BaseUndertowTest { } @Test + public void testHttpSimpleWithQuery() throws Exception { + getMockEndpoint("mock:input").expectedHeaderReceived(Exchange.HTTP_METHOD, "GET"); + getMockEndpoint("mock:input").expectedHeaderReceived("name", "me"); + + String out = template.requestBody("undertow:http://localhost:{{port}}/foo?name=me", null, String.class); + assertEquals("Bye World", out); + + assertMockEndpointsSatisfied(); + } + + @Test public void testHttpSimpleHeader() throws Exception { getMockEndpoint("mock:input").expectedHeaderReceived(Exchange.HTTP_METHOD, "POST");