Repository: camel Updated Branches: refs/heads/camel-2.16.x c8dd8419c -> df59df3fd refs/heads/master 5d305baa8 -> b2ae549e0
CAMEL-9270 trim headers before setting them via Restlet API Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/41c316b7 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/41c316b7 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/41c316b7 Branch: refs/heads/master Commit: 41c316b76b1d4f9d6fd667a62c2377160a76a513 Parents: 5d305ba Author: Anton Koscejev <anton.kosce...@zoomint.com> Authored: Mon Nov 30 15:27:09 2015 +0100 Committer: Claus Ibsen <davscl...@apache.org> Committed: Mon Nov 30 16:40:27 2015 +0100 ---------------------------------------------------------------------- components/camel-restlet/pom.xml | 7 +- .../restlet/DefaultRestletBinding.java | 83 +++++++++----------- .../component/restlet/RestRestletCorsTest.java | 73 +++++++++++++++++ 3 files changed, 118 insertions(+), 45 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/41c316b7/components/camel-restlet/pom.xml ---------------------------------------------------------------------- diff --git a/components/camel-restlet/pom.xml b/components/camel-restlet/pom.xml index a9bcd19..f85a273 100644 --- a/components/camel-restlet/pom.xml +++ b/components/camel-restlet/pom.xml @@ -27,7 +27,7 @@ <artifactId>camel-restlet</artifactId> <packaging>bundle</packaging> <name>Camel :: Restlet</name> - <description>Camel REST (Restlet baesd) Component</description> + <description>Camel REST (Restlet based) Component</description> <properties> <camel.osgi.export.pkg> @@ -113,6 +113,11 @@ <artifactId>spring-test</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + <scope>test</scope> + </dependency> </dependencies> http://git-wip-us.apache.org/repos/asf/camel/blob/41c316b7/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/DefaultRestletBinding.java ---------------------------------------------------------------------- diff --git a/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/DefaultRestletBinding.java b/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/DefaultRestletBinding.java index d0882f7..32cd8ae 100644 --- a/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/DefaultRestletBinding.java +++ b/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/DefaultRestletBinding.java @@ -38,6 +38,7 @@ import javax.xml.transform.dom.DOMSource; import org.apache.camel.Exchange; import org.apache.camel.Message; import org.apache.camel.StringSource; +import org.apache.camel.TypeConverter; import org.apache.camel.WrappedFile; import org.apache.camel.component.file.GenericFile; import org.apache.camel.spi.HeaderFilterStrategy; @@ -383,39 +384,12 @@ public class DefaultRestletBinding implements RestletBinding, HeaderFilterStrate return true; } if (header.equalsIgnoreCase(HeaderConstants.HEADER_ACCESS_CONTROL_ALLOW_HEADERS)) { - Set set; - if (value instanceof Set) { - set = (Set) value; - } else { - set = new LinkedHashSet(); - Iterator it = ObjectHelper.createIterator(value); - while (it.hasNext()) { - Object next = it.next(); - String text = exchange.getContext().getTypeConverter().tryConvertTo(String.class, next); - if (text != null) { - set.add(text); - } - } - } + Set<String> set = convertToStringSet(value, exchange.getContext().getTypeConverter()); message.setAccessControlAllowHeaders(set); return true; } if (header.equalsIgnoreCase(HeaderConstants.HEADER_ACCESS_CONTROL_ALLOW_METHODS)) { - Set set; - if (value instanceof Set) { - set = (Set) value; - } else { - set = new LinkedHashSet(); - Iterator it = ObjectHelper.createIterator(value); - while (it.hasNext()) { - Object next = it.next(); - String text = exchange.getContext().getTypeConverter().tryConvertTo(String.class, next); - if (text != null) { - Method method = new Method(text); - set.add(method); - } - } - } + Set<Method> set = convertToMethodSet(value, exchange.getContext().getTypeConverter()); message.setAccessControlAllowMethods(set); return true; } @@ -427,21 +401,7 @@ public class DefaultRestletBinding implements RestletBinding, HeaderFilterStrate return true; } if (header.equalsIgnoreCase(HeaderConstants.HEADER_ACCESS_CONTROL_EXPOSE_HEADERS)) { - Set set; - if (value instanceof Set) { - set = (Set) value; - } else { - set = new LinkedHashSet(); - Iterator it = ObjectHelper.createIterator(value); - while (it.hasNext()) { - Object next = it.next(); - String text = exchange.getContext().getTypeConverter().tryConvertTo(String.class, next); - if (text != null) { - Method method = new Method(text); - set.add(method); - } - } - } + Set<String> set = convertToStringSet(value, exchange.getContext().getTypeConverter()); message.setAccessControlExposeHeaders(set); return true; } @@ -526,6 +486,41 @@ public class DefaultRestletBinding implements RestletBinding, HeaderFilterStrate return false; } + @SuppressWarnings("unchecked") + private Set<String> convertToStringSet(Object value, TypeConverter typeConverter) { + if (value instanceof Set) { + return (Set<String>) value; + } + Set<String> set = new LinkedHashSet<>(); + Iterator it = ObjectHelper.createIterator(value); + while (it.hasNext()) { + Object next = it.next(); + String text = typeConverter.tryConvertTo(String.class, next); + if (text != null) { + set.add(text.trim()); + } + } + return set; + } + + @SuppressWarnings("unchecked") + private Set<Method> convertToMethodSet(Object value, TypeConverter typeConverter) { + if (value instanceof Set) { + return (Set<Method>) value; + } + Set<Method> set = new LinkedHashSet<>(); + Iterator it = ObjectHelper.createIterator(value); + while (it.hasNext()) { + Object next = it.next(); + String text = typeConverter.tryConvertTo(String.class, next); + if (text != null) { + Method method = Method.valueOf(text.trim()); // creates new instance only if no matching instance exists + set.add(method); + } + } + return set; + } + public HeaderFilterStrategy getHeaderFilterStrategy() { return headerFilterStrategy; } http://git-wip-us.apache.org/repos/asf/camel/blob/41c316b7/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/RestRestletCorsTest.java ---------------------------------------------------------------------- diff --git a/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/RestRestletCorsTest.java b/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/RestRestletCorsTest.java new file mode 100644 index 0000000..3c4ff68 --- /dev/null +++ b/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/RestRestletCorsTest.java @@ -0,0 +1,73 @@ +package org.apache.camel.component.restlet; + +import java.util.Set; + +import com.google.common.base.Splitter; +import org.apache.camel.Exchange; +import org.apache.camel.Message; +import org.apache.camel.Processor; +import org.apache.camel.builder.RouteBuilder; +import org.junit.Test; + +import static com.google.common.collect.Sets.newHashSet; +import static org.hamcrest.CoreMatchers.is; + +public class RestRestletCorsTest extends RestletTestSupport { + Splitter headerSplitter = Splitter.on(",").trimResults(); + + @Test + public void testRestletProducerGet() throws Exception { + Exchange exchange = template.request("http://localhost:" + portNum + "/users/123/basic", null); + + // verify no problems have occurred: + assertFalse(exchange.isFailed()); + Message message = exchange.getOut(); + assertThat(message.getHeader(Exchange.HTTP_RESPONSE_CODE, Integer.class), is(200)); + + // verify all header values match those specified in restConfiguration: + assertThat(message.getHeader("Access-Control-Allow-Origin", String.class), is("https://localhost:443")); + assertHeaderSet(message, "Access-Control-Allow-Methods", "GET", "POST", "PUT", "DELETE", "OPTIONS"); + assertHeaderSet(message, "Access-Control-Allow-Headers", + "Origin", "Accept", "Content-Type", "Access-Control-Request-Method", "Access-Control-Request-Headers"); + assertThat(message.getHeader("Access-Control-Max-Age", Integer.class), is(1234)); + } + + private void assertHeaderSet(Message message, String headerName, String... headerValues) { + // compare header values as sets: ignore order, all required values are present and nothing more: + String allowHeaders = message.getHeader(headerName, String.class); + Set<String> actual = newHashSet(headerSplitter.split(allowHeaders)); + Set<String> expected = newHashSet(headerValues); + assertThat(actual, is(expected)); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + // configure to use restlet on localhost with the given port + restConfiguration() + .component("restlet").host("localhost").port(portNum) + .enableCORS(true) + .corsHeaderProperty("Access-Control-Allow-Origin", "https://localhost:443") + .corsHeaderProperty("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS") + .corsHeaderProperty("Access-Control-Allow-Headers", + "Origin, Accept, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers") + .corsHeaderProperty("Access-Control-Max-Age", "1234"); + + // use the rest DSL to define the rest services + rest("/users/") + .get("{id}/basic") + .route() + .to("mock:input") + .process(new Processor() { + public void process(Exchange exchange) throws Exception { + String id = exchange.getIn().getHeader("id", String.class); + exchange.getOut().setBody(id + ";Donald Duck"); + } + }); + } + }; + } +} +