Author: davsclaus
Date: Wed May  1 16:27:29 2013
New Revision: 1478078

URL: http://svn.apache.org/r1478078
Log:
CAMEL-6327: More work on new camel-netty-http component.

Modified:
    
camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/DefaultNettyHttpBinding.java
    
camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/HttpClientPipelineFactory.java
    
camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/HttpServerPipelineFactory.java
    
camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpBinding.java
    
camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConverter.java
    
camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpMessage.java
    
camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/handlers/HttpClientChannelHandler.java
    
camel/trunk/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpProducerSimpleTest.java
    
camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/handlers/ClientChannelHandler.java

Modified: 
camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/DefaultNettyHttpBinding.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/DefaultNettyHttpBinding.java?rev=1478078&r1=1478077&r2=1478078&view=diff
==============================================================================
--- 
camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/DefaultNettyHttpBinding.java
 (original)
+++ 
camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/DefaultNettyHttpBinding.java
 Wed May  1 16:27:29 2013
@@ -58,7 +58,7 @@ public class DefaultNettyHttpBinding imp
     public Message toCamelMessage(HttpRequest request, Exchange exchange) 
throws Exception {
         LOG.trace("toCamelMessage: {}", request);
 
-        NettyHttpMessage answer = new NettyHttpMessage(request, this);
+        NettyHttpMessage answer = new NettyHttpMessage(request, null, this);
         // force getting headers which will populate them
         answer.getHeaders();
 
@@ -99,6 +99,46 @@ public class DefaultNettyHttpBinding imp
     }
 
     @Override
+    public Message toCamelMessage(HttpResponse response, Exchange exchange) 
throws Exception {
+        LOG.trace("toCamelMessage: {}", response);
+
+        NettyHttpMessage answer = new NettyHttpMessage(null, response, this);
+        // force getting headers which will populate them
+        answer.getHeaders();
+
+        // keep the body as is, and use type converters
+        answer.setBody(response.getContent());
+        return answer;
+    }
+
+    @Override
+    public void populateCamelHeaders(HttpResponse response, Map<String, 
Object> headers, Exchange exchange) throws Exception {
+        LOG.trace("populateCamelHeaders: {}", response);
+
+        headers.put(Exchange.HTTP_RESPONSE_CODE, 
response.getStatus().getCode());
+        // TODO: use another status header
+        headers.put("CamelHttpResponseText", 
response.getStatus().getReasonPhrase());
+
+        for (String name : response.getHeaderNames()) {
+            // mapping the content-type
+            if (name.toLowerCase().equals("content-type")) {
+                name = Exchange.CONTENT_TYPE;
+            }
+            // add the headers one by one, and use the header filter strategy
+            List<String> values = response.getHeaders(name);
+            Iterator<?> it = ObjectHelper.createIterator(values);
+            while (it.hasNext()) {
+                Object extracted = it.next();
+                LOG.trace("HTTP-header: {}", extracted);
+                if (headerFilterStrategy != null
+                        && 
!headerFilterStrategy.applyFilterToExternalHeaders(name, extracted, exchange)) {
+                    NettyHttpHelper.appendHeader(headers, name, extracted);
+                }
+            }
+        }
+    }
+
+    @Override
     public HttpResponse toNettyResponse(Message message) throws Exception {
         LOG.trace("toNettyResponse: {}", message);
 

Modified: 
camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/HttpClientPipelineFactory.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/HttpClientPipelineFactory.java?rev=1478078&r1=1478077&r2=1478078&view=diff
==============================================================================
--- 
camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/HttpClientPipelineFactory.java
 (original)
+++ 
camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/HttpClientPipelineFactory.java
 Wed May  1 16:27:29 2013
@@ -37,14 +37,14 @@ import org.slf4j.LoggerFactory;
 public class HttpClientPipelineFactory extends ClientPipelineFactory {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(HttpClientPipelineFactory.class);
-    private NettyProducer producer;
+    private NettyHttpProducer producer;
     private SSLContext sslContext;
 
     public HttpClientPipelineFactory() {
         // default constructor needed
     }
 
-    public HttpClientPipelineFactory(NettyProducer nettyProducer) {
+    public HttpClientPipelineFactory(NettyHttpProducer nettyProducer) {
         this.producer = nettyProducer;
         try {
             this.sslContext = createSSLContext(producer);
@@ -52,12 +52,14 @@ public class HttpClientPipelineFactory e
             throw ObjectHelper.wrapRuntimeCamelException(e);
         }
 
-        LOG.info("Created SslContext {}", sslContext);
+        if (sslContext != null) {
+            LOG.info("Created SslContext {}", sslContext);
+        }
     }
 
     @Override
     public ClientPipelineFactory createPipelineFactory(NettyProducer 
nettyProducer) {
-        return new HttpClientPipelineFactory(nettyProducer);
+        return new HttpClientPipelineFactory((NettyHttpProducer) 
nettyProducer);
     }
 
     @Override

Modified: 
camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/HttpServerPipelineFactory.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/HttpServerPipelineFactory.java?rev=1478078&r1=1478077&r2=1478078&view=diff
==============================================================================
--- 
camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/HttpServerPipelineFactory.java
 (original)
+++ 
camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/HttpServerPipelineFactory.java
 Wed May  1 16:27:29 2013
@@ -55,7 +55,9 @@ public class HttpServerPipelineFactory e
             throw ObjectHelper.wrapRuntimeCamelException(e);
         }
 
-        LOG.info("Created SslContext {}", sslContext);
+        if (sslContext != null) {
+            LOG.info("Created SslContext {}", sslContext);
+        }
     }
 
     @Override

Modified: 
camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpBinding.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpBinding.java?rev=1478078&r1=1478077&r2=1478078&view=diff
==============================================================================
--- 
camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpBinding.java
 (original)
+++ 
camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpBinding.java
 Wed May  1 16:27:29 2013
@@ -50,7 +50,27 @@ public interface NettyHttpBinding {
     void populateCamelHeaders(HttpRequest request, Map<String, Object> 
headers, Exchange exchange) throws Exception;
 
     /**
-     * Binds from Camel {@link Message} to Netty {@link 
org.jboss.netty.handler.codec.http.HttpResponse}.
+     * Binds from Netty {@link HttpResponse} to Camel {@Message}.
+     *
+     * @param response  the netty http response
+     * @param exchange  the exchange that should contain the returned message.
+     * @return the message to store on the given exchange
+     * @throws Exception is thrown if error during binding
+     */
+    Message toCamelMessage(HttpResponse response, Exchange exchange) throws 
Exception;
+
+    /**
+     * Binds from Netty {@link HttpResponse} to Camel headers as a {@link Map}.
+     *
+     * @param response   the netty http response
+     * @param headers   the Camel headers that should be populated
+     * @param exchange  the exchange that should contain the returned message.
+     * @throws Exception is thrown if error during binding
+     */
+    void populateCamelHeaders(HttpResponse response, Map<String, Object> 
headers, Exchange exchange) throws Exception;
+
+    /**
+     * Binds from Camel {@link Message} to Netty {@link HttpResponse}.
      *
      * @param message  the Camel message
      * @return the http response

Modified: 
camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConverter.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConverter.java?rev=1478078&r1=1478077&r2=1478078&view=diff
==============================================================================
--- 
camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConverter.java
 (original)
+++ 
camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConverter.java
 Wed May  1 16:27:29 2013
@@ -42,7 +42,12 @@ public final class NettyHttpConverter {
             // okay we may need to cheat a bit when we want to grab the 
HttpRequest as its stored on the NettyHttpMessage
             // so if the message instance is a NettyHttpMessage and its body 
is the value, then we can grab the
             // HttpRequest from the NettyHttpMessage
-            NettyHttpMessage msg = exchange.getIn(NettyHttpMessage.class);
+            NettyHttpMessage msg;
+            if (exchange.hasOut()) {
+                msg = exchange.getOut(NettyHttpMessage.class);
+            } else {
+                msg = exchange.getIn(NettyHttpMessage.class);
+            }
             if (msg != null && msg.getBody() == value) {
                 return msg.getHttpRequest();
             }
@@ -51,6 +56,31 @@ public final class NettyHttpConverter {
         return null;
     }
 
+    /**
+     * A fallback converter that allows us to easily call Java beans and use 
the raw Netty {@link HttpRequest} as parameter types.
+     */
+    @FallbackConverter
+    public static Object convertToHttpResponse(Class<?> type, Exchange 
exchange, Object value, TypeConverterRegistry registry) {
+        // if we want to covert to convertToHttpResponse
+        if (value != null && HttpResponse.class.isAssignableFrom(type)) {
+
+            // okay we may need to cheat a bit when we want to grab the 
HttpRequest as its stored on the NettyHttpMessage
+            // so if the message instance is a NettyHttpMessage and its body 
is the value, then we can grab the
+            // HttpRequest from the NettyHttpMessage
+            NettyHttpMessage msg;
+            if (exchange.hasOut()) {
+                msg = exchange.getOut(NettyHttpMessage.class);
+            } else {
+                msg = exchange.getIn(NettyHttpMessage.class);
+            }
+            if (msg != null && msg.getBody() == value) {
+                return msg.getHttpResponse();
+            }
+        }
+
+        return null;
+    }
+
     @Converter
     public static String toString(HttpResponse response, Exchange exchange) {
         String contentType = response.getHeader(Exchange.CONTENT_TYPE);

Modified: 
camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpMessage.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpMessage.java?rev=1478078&r1=1478077&r2=1478078&view=diff
==============================================================================
--- 
camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpMessage.java
 (original)
+++ 
camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpMessage.java
 Wed May  1 16:27:29 2013
@@ -21,6 +21,7 @@ import java.util.Map;
 import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.impl.DefaultMessage;
 import org.jboss.netty.handler.codec.http.HttpRequest;
+import org.jboss.netty.handler.codec.http.HttpResponse;
 
 /**
  * Netty HTTP based {@link org.apache.camel.Message}.
@@ -31,10 +32,12 @@ import org.jboss.netty.handler.codec.htt
 public class NettyHttpMessage extends DefaultMessage {
 
     private final transient HttpRequest httpRequest;
+    private final transient HttpResponse httpResponse;
     private final transient NettyHttpBinding httpBinding;
 
-    public NettyHttpMessage(HttpRequest httpRequest, NettyHttpBinding 
httpBinding) {
+    public NettyHttpMessage(HttpRequest httpRequest, HttpResponse 
httpResponse, NettyHttpBinding httpBinding) {
         this.httpRequest = httpRequest;
+        this.httpResponse = httpResponse;
         this.httpBinding = httpBinding;
     }
 
@@ -42,10 +45,18 @@ public class NettyHttpMessage extends De
         return httpRequest;
     }
 
+    public HttpResponse getHttpResponse() {
+        return httpResponse;
+    }
+
     @Override
     protected void populateInitialHeaders(Map<String, Object> map) {
         try {
-            httpBinding.populateCamelHeaders(httpRequest, map, getExchange());
+            if (httpRequest != null) {
+                httpBinding.populateCamelHeaders(httpRequest, map, 
getExchange());
+            } else {
+                httpBinding.populateCamelHeaders(httpResponse, map, 
getExchange());
+            }
         } catch (Exception e) {
             throw new RuntimeCamelException("Error populating initial 
headers", e);
         }
@@ -53,6 +64,6 @@ public class NettyHttpMessage extends De
 
     @Override
     public DefaultMessage newInstance() {
-        return new NettyHttpMessage(httpRequest, httpBinding);
+        return new NettyHttpMessage(httpRequest, httpResponse, httpBinding);
     }
 }

Modified: 
camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/handlers/HttpClientChannelHandler.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/handlers/HttpClientChannelHandler.java?rev=1478078&r1=1478077&r2=1478078&view=diff
==============================================================================
--- 
camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/handlers/HttpClientChannelHandler.java
 (original)
+++ 
camel/trunk/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/handlers/HttpClientChannelHandler.java
 Wed May  1 16:27:29 2013
@@ -16,26 +16,44 @@
  */
 package org.apache.camel.component.netty.http.handlers;
 
-import org.apache.camel.component.netty.NettyProducer;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
 import org.apache.camel.component.netty.handlers.ClientChannelHandler;
 import org.apache.camel.component.netty.http.NettyHttpProducer;
 import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.channel.MessageEvent;
+import org.jboss.netty.handler.codec.http.HttpResponse;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+/**
+ * Netty HTTP {@link 
org.apache.camel.component.netty.handlers.ClientChannelHandler} that handles 
the response combing
+ * back from thhe HTTP server, called by this client.
+ *
+ */
 public class HttpClientChannelHandler extends ClientChannelHandler {
 
-    // use NettyHttpConsumer as logger to make it easier to read the logs as 
this is part of the producer
+    // use NettyHttpProducer as logger to make it easier to read the logs as 
this is part of the producer
     private static final transient Logger LOG = 
LoggerFactory.getLogger(NettyHttpProducer.class);
+    private final NettyHttpProducer producer;
+    private HttpResponse response;
 
-    public HttpClientChannelHandler(NettyProducer producer) {
+    public HttpClientChannelHandler(NettyHttpProducer producer) {
         super(producer);
+        this.producer = producer;
     }
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent 
messageEvent) throws Exception {
-        super.messageReceived(ctx, messageEvent);    //To change body of 
overridden methods use File | Settings | File Templates.
+        // store response, as this channel handler is created per pipeline
+        response = (HttpResponse) messageEvent.getMessage();
+
+        super.messageReceived(ctx, messageEvent);
     }
 
+    @Override
+    protected Message getResponseMessage(Exchange exchange, MessageEvent 
messageEvent) throws Exception {
+        // use the binding
+        return 
producer.getEndpoint().getNettyHttpBinding().toCamelMessage(response, exchange);
+    }
 }

Modified: 
camel/trunk/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpProducerSimpleTest.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpProducerSimpleTest.java?rev=1478078&r1=1478077&r2=1478078&view=diff
==============================================================================
--- 
camel/trunk/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpProducerSimpleTest.java
 (original)
+++ 
camel/trunk/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpProducerSimpleTest.java
 Wed May  1 16:27:29 2013
@@ -16,7 +16,10 @@
  */
 package org.apache.camel.component.netty.http;
 
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
 import org.apache.camel.builder.RouteBuilder;
+import org.jboss.netty.handler.codec.http.HttpResponse;
 import org.junit.Test;
 
 public class NettyHttpProducerSimpleTest extends BaseNettyTest {
@@ -31,6 +34,31 @@ public class NettyHttpProducerSimpleTest
         assertMockEndpointsSatisfied();
     }
 
+    @Test
+    public void testHttpSimpleExchange() throws Exception {
+        getMockEndpoint("mock:input").expectedBodiesReceived("Hello World");
+
+        Exchange out = 
template.request("netty-http:http://localhost:{{port}}/foo";, new Processor() {
+            @Override
+            public void process(Exchange exchange) throws Exception {
+                exchange.getIn().setBody("Hello World");
+            }
+        });
+        assertNotNull(out);
+        assertTrue(out.hasOut());
+
+        NettyHttpMessage response = out.getOut(NettyHttpMessage.class);
+        assertNotNull(response);
+        assertEquals(200, response.getHttpResponse().getStatus().getCode());
+
+        // we can also get the response as body
+        HttpResponse body = out.getOut().getBody(HttpResponse.class);
+        assertNotNull(body);
+        assertEquals(200, body.getStatus().getCode());
+
+        assertMockEndpointsSatisfied();
+    }
+
     @Override
     protected RouteBuilder createRouteBuilder() throws Exception {
         return new RouteBuilder() {

Modified: 
camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/handlers/ClientChannelHandler.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/handlers/ClientChannelHandler.java?rev=1478078&r1=1478077&r2=1478078&view=diff
==============================================================================
--- 
camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/handlers/ClientChannelHandler.java
 (original)
+++ 
camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/handlers/ClientChannelHandler.java
 Wed May  1 16:27:29 2013
@@ -19,7 +19,7 @@ package org.apache.camel.component.netty
 import org.apache.camel.AsyncCallback;
 import org.apache.camel.CamelExchangeException;
 import org.apache.camel.Exchange;
-import org.apache.camel.NoTypeConversionAvailableException;
+import org.apache.camel.Message;
 import org.apache.camel.component.netty.NettyCamelState;
 import org.apache.camel.component.netty.NettyConstants;
 import org.apache.camel.component.netty.NettyHelper;
@@ -125,27 +125,20 @@ public class ClientChannelHandler extend
         Exchange exchange = getExchange(ctx);
         AsyncCallback callback = getAsyncCallback(ctx);
 
-        Object body = messageEvent.getMessage();
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("Channel: {} received body: {}", new 
Object[]{messageEvent.getChannel(), body});
-        }
-
-        // if textline enabled then covert to a String which must be used for 
textline
-        if (producer.getConfiguration().isTextline()) {
-            try {
-                body = 
producer.getContext().getTypeConverter().mandatoryConvertTo(String.class, 
exchange, body);
-            } catch (NoTypeConversionAvailableException e) {
-                exchange.setException(e);
-                callback.done(false);
-            }
+        Message message;
+        try {
+            message = getResponseMessage(exchange, messageEvent);
+        } catch (Exception e) {
+            exchange.setException(e);
+            callback.done(false);
+            return;
         }
 
-
         // set the result on either IN or OUT on the original exchange 
depending on its pattern
         if (ExchangeHelper.isOutCapable(exchange)) {
-            NettyPayloadHelper.setOut(exchange, body);
+            exchange.setOut(message);
         } else {
-            NettyPayloadHelper.setIn(exchange, body);
+            exchange.setIn(message);
         }
 
         try {
@@ -174,6 +167,37 @@ public class ClientChannelHandler extend
         }
     }
 
+    /**
+     * Gets the Camel {@link Message} to use as the message to be set on the 
current {@link Exchange} when
+     * we have received a reply message.
+     * <p/>
+     *
+     * @param exchange      the current exchange
+     * @param messageEvent  the incoming event which has the response message 
from Netty.
+     * @return the Camel {@link Message} to set on the current {@link 
Exchange} as the response message.
+     * @throws Exception is thrown if error getting the response message
+     */
+    protected Message getResponseMessage(Exchange exchange, MessageEvent 
messageEvent) throws Exception {
+        Object body = messageEvent.getMessage();
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Channel: {} received body: {}", new 
Object[]{messageEvent.getChannel(), body});
+        }
+
+        // if textline enabled then covert to a String which must be used for 
textline
+        if (producer.getConfiguration().isTextline()) {
+           body = 
producer.getContext().getTypeConverter().mandatoryConvertTo(String.class, 
exchange, body);
+        }
+
+        // set the result on either IN or OUT on the original exchange 
depending on its pattern
+        if (ExchangeHelper.isOutCapable(exchange)) {
+            NettyPayloadHelper.setOut(exchange, body);
+            return exchange.getOut();
+        } else {
+            NettyPayloadHelper.setIn(exchange, body);
+            return exchange.getIn();
+        }
+    }
+
     private Exchange getExchange(ChannelHandlerContext ctx) {
         NettyCamelState state = producer.getState(ctx.getChannel());
         return state != null ? state.getExchange() : null;


Reply via email to