CAMEL-10665: Setting restlet standard headers should be done via their special api instead of making it easy :(
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/93c30cf6 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/93c30cf6 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/93c30cf6 Branch: refs/heads/master Commit: 93c30cf6f3e783a4a01a24f5852b68e9e0d448e3 Parents: f8f6069 Author: Claus Ibsen <davscl...@apache.org> Authored: Thu Oct 5 11:24:57 2017 +0200 Committer: Claus Ibsen <davscl...@apache.org> Committed: Thu Oct 5 13:37:17 2017 +0200 ---------------------------------------------------------------------- components/camel-restlet/pom.xml | 11 ++++ .../restlet/DefaultRestletBinding.java | 65 +++++++++++++++---- ...estletProducerStandardHeaderWarningTest.java | 68 ++++++++++++++++++++ 3 files changed, 133 insertions(+), 11 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/93c30cf6/components/camel-restlet/pom.xml ---------------------------------------------------------------------- diff --git a/components/camel-restlet/pom.xml b/components/camel-restlet/pom.xml index 5a8570e..84f5cf8 100644 --- a/components/camel-restlet/pom.xml +++ b/components/camel-restlet/pom.xml @@ -135,6 +135,17 @@ <scope>test</scope> </dependency> <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-jul</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>jul-to-slf4j</artifactId> + <version>${slf4j-version}</version> + <scope>test</scope> + </dependency> + <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> http://git-wip-us.apache.org/repos/asf/camel/blob/93c30cf6/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 ac52102..70f9806 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 @@ -65,6 +65,7 @@ import org.restlet.data.Preference; import org.restlet.data.Status; import org.restlet.engine.application.DecodeRepresentation; import org.restlet.engine.header.HeaderConstants; +import org.restlet.engine.header.HeaderUtils; import org.restlet.representation.ByteArrayRepresentation; import org.restlet.representation.EmptyRepresentation; import org.restlet.representation.FileRepresentation; @@ -293,23 +294,65 @@ public class DefaultRestletBinding implements RestletBinding, HeaderFilterStrate } } - // accept - String accept = exchange.getIn().getHeader("Accept", String.class); - final ClientInfo clientInfo = request.getClientInfo(); - final List<Preference<MediaType>> acceptedMediaTypesList = clientInfo.getAcceptedMediaTypes(); - if (accept != null) { - final MediaType[] acceptedMediaTypes = exchange.getContext().getTypeConverter().tryConvertTo(MediaType[].class, exchange, accept); - for (final MediaType acceptedMediaType : acceptedMediaTypes) { - acceptedMediaTypesList.add(new Preference<MediaType>(acceptedMediaType)); - } - } + // filter out standard restlet headers which must be configured differently + org.restlet.Message extensionHeaders = new Request(); + HeaderUtils.copyExtensionHeaders(restletHeaders, extensionHeaders); + + // setup standard headers + Series<Header> standardHeaders = new Series<>(Header.class); + standardHeaders.addAll(restletHeaders); + standardHeaders.removeAll(extensionHeaders.getHeaders()); + + // setup extension headers + restletHeaders.removeAll(standardHeaders); + + // now add standard headers but via the special restlet api + LOG.debug("Detected {} extension headers", extensionHeaders.getHeaders().size()); + LOG.debug("Detected {} standard headers", standardHeaders.size()); + + configureRestletStandardHeaders(exchange, request, standardHeaders); + + // deprecated accept final MediaType[] acceptedMediaTypes = exchange.getIn().getHeader(Exchange.ACCEPT_CONTENT_TYPE, MediaType[].class); if (acceptedMediaTypes != null) { - for (final MediaType acceptedMediaType : acceptedMediaTypes) { + ClientInfo clientInfo = request.getClientInfo(); + List<Preference<MediaType>> acceptedMediaTypesList = clientInfo.getAcceptedMediaTypes(); + for (MediaType acceptedMediaType : acceptedMediaTypes) { acceptedMediaTypesList.add(new Preference<MediaType>(acceptedMediaType)); } } + } + private void configureRestletStandardHeaders(Exchange exchange, Request request, Series standardHeaders) { + Iterator it = standardHeaders.iterator(); + while (it.hasNext()) { + Header h = (Header) it.next(); + String key = h.getName(); + String value = h.getValue(); + if ("Authorization".equalsIgnoreCase(key)) { + // special workaround for restlet (https://github.com/restlet/restlet-framework-java/issues/1086) + ChallengeResponse c = new ChallengeResponse(new ChallengeScheme("", "")); + c.setRawValue(value); + request.setChallengeResponse(c); + continue; + } else if ("Accept".equalsIgnoreCase(key)) { + ClientInfo clientInfo = request.getClientInfo(); + List<Preference<MediaType>> acceptedMediaTypesList = clientInfo.getAcceptedMediaTypes(); + MediaType[] acceptedMediaTypes = exchange.getContext().getTypeConverter().tryConvertTo(MediaType[].class, exchange, value); + for (MediaType acceptedMediaType : acceptedMediaTypes) { + acceptedMediaTypesList.add(new Preference<MediaType>(acceptedMediaType)); + } + continue; + } else if ("Content-Type".equalsIgnoreCase(key)) { + MediaType mediaType = exchange.getContext().getTypeConverter().tryConvertTo(MediaType.class, exchange, value); + if (mediaType != null) { + request.getEntity().setMediaType(mediaType); + } + continue; + } + // TODO: implement all the other restlet standard headers + LOG.warn("Addition of the standard header \"{}\" is not allowed. Please use the equivalent property in the Restlet API.", key); + } } public void populateRestletResponseFromExchange(Exchange exchange, Response response) throws Exception { http://git-wip-us.apache.org/repos/asf/camel/blob/93c30cf6/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/RestletProducerStandardHeaderWarningTest.java ---------------------------------------------------------------------- diff --git a/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/RestletProducerStandardHeaderWarningTest.java b/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/RestletProducerStandardHeaderWarningTest.java new file mode 100644 index 0000000..8037eae --- /dev/null +++ b/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/RestletProducerStandardHeaderWarningTest.java @@ -0,0 +1,68 @@ +/** + * 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.restlet; + +import java.util.logging.Level; + +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.builder.RouteBuilder; +import org.junit.Test; +import org.slf4j.bridge.SLF4JBridgeHandler; + +/** + * @version + */ +public class RestletProducerStandardHeaderWarningTest extends RestletTestSupport { + + @Test + public void testRestletProducerAuthorizationGet() throws Exception { + // restlet uses the JUL logger which is a pain to configure/install + // we should not see WARN logs + SLF4JBridgeHandler.install(); + java.util.logging.LogManager.getLogManager().getLogger("").setLevel(Level.INFO); + + String out = fluentTemplate.to("direct:start") + .withHeader("id", 123).withHeader("Authorization", "myuser") + .request(String.class); + assertEquals("123;Donald Duck;myuser", out); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + from("direct:start").to("restlet:http://localhost:" + portNum + "/users/{id}/basic").to("log:reply"); + + from("restlet:http://localhost:" + portNum + "/users/{id}/basic?restletMethods=GET,DELETE") + .process(new Processor() { + public void process(Exchange exchange) throws Exception { + String authorization = exchange.getIn().getHeader("Authorization", String.class); + log.info("Authorization header: {}", authorization); + String id = exchange.getIn().getHeader("id", String.class); + exchange.getOut().setBody(id + ";Donald Duck"); + if (authorization != null) { + String body = exchange.getOut().getBody(String.class) + ";" + authorization; + exchange.getOut().setBody(body); + } + } + }); + } + }; + } +}