Akka-Camel jetty:http Java how to get client ip address

1,496 views
Skip to first unread message

Cédric Sougné

unread,
Nov 13, 2013, 7:36:46 AM11/13/13
to akka...@googlegroups.com
Hi,

I'm trying to get client ip address using akka-camel consumer actor and the jetty:http: camel component.

Inspecting headers, I've found a _remoteaddr from camelHttpServletRequest but value is null.

Thanks for your suggestions.

Best regards,

Cédric



√iktor Ҡlang

unread,
Nov 13, 2013, 8:13:05 AM11/13/13
to Akka User List
What does the Camel Jetty component documentation say?


--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://akka.io/faq/
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+...@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/groups/opt_out.



--
Cheers,

Viktor Klang

Director of Engineering

Twitter: @viktorklang

Cédric Sougné

unread,
Nov 13, 2013, 9:22:35 AM11/13/13
to akka...@googlegroups.com
I see nothing about that on the camel-jetty component page but googling telled me that I should be able to retrieve Jetty's HttpServletRequest object. This contains the complete client address information. The question is how to retrieve this from the consumer actor?

Cédric Sougné

unread,
Nov 14, 2013, 5:29:00 AM11/14/13
to akka...@googlegroups.com
finally got it by adding a Processor to the camel RouteDefinition. the Processor add a header to the camelmessage with source address.

Thanks for RTFM reminder :-)

√iktor Ҡlang

unread,
Nov 14, 2013, 5:31:55 AM11/14/13
to Akka User List
Happy hAkking!

Daniel Collins

unread,
Jan 6, 2014, 2:48:46 PM1/6/14
to akka...@googlegroups.com
Hey guys,

Sorry to open this thread again, but I have been trying to accomplish the same thing (Jetty), but haven't had any luck. I have read through this but still feel quite stranded. Almost all documentation outside that page is for direct-java or DSL implementations, whereas with akka you extend the Consumer class, define your endpoint, and you're good to go. I'm afraid to start blindly hacking my way to raw camel objects because I don't know how Akka implements the underlying camel objects and am nervous I will start hardwiring to stuff I don't completely understand or creating duplicate instances or other unintended consequences that will give me more problems than solutions.

Up to this point I have handles to my JettyHttpComponent and CamelContext in my Consumer actor constructor. Cedric mentioned a custom Processor, so I am guessing I can get the client IP from the Exchange object somehow. If I were to figure that out, I'm not sure how I would wire that into my consumer actor. Would I define it in my endpoint string which would then point to the actual definition elsewhere, or do I somehow override a consumer method? I haven't found any methods in either the JettyHttpComponent/CamelContext objects that I think would do the trick.

Any additional hints or musings would be greatly appreciated!

Cédric Sougné

unread,
Jan 7, 2014, 3:57:02 AM1/7/14
to akka...@googlegroups.com
You'll have to create a camel Processor that will fill the exchange sourceAddr header from httpRequest:

public class SimpleProcessor implements Processor{

    @Override
    public void process(Exchange exchange) {
        Message inMsg = exchange.getIn();

        // extract the Jetty HttpServletRequest, from there we can extract
        // the remote client address.
        HttpServletRequest req = exchange.getIn().getBody(HttpServletRequest.class);
        if (req != null) {
            String remoteAddr = req.getRemoteAddr();
            int remotePort = req.getRemotePort();
            System.out.println("Client called from " + remoteAddr + ":" + remotePort);
            exchange.getIn().setHeader("sourceAddr", remoteAddr);
        } else {
            //System.out.println("Could not extract client address!</body></html>");
        }
    }
}

but without setting reply body as my consumer actor will handle this.

then akka documentation will help you to intercept route construction :

concretely, in your UntypedConsumerActor:

@Override
    public Mapper<RouteDefinition, ProcessorDefinition<?>> getRouteDefinitionHandler() {
        return mapper; //To change body of generated methods, choose Tools | Templates.

    }

private static Mapper<RouteDefinition, ProcessorDefinition<?>> mapper
            = new Mapper<RouteDefinition, ProcessorDefinition<?>>() {
                @Override
                public ProcessorDefinition<?> apply(RouteDefinition rd) {
                    return rd.bean(org.acis_group.alec.system.utils.SimpleProcessor.class);
                }
            };

then you'll be able to axtract Ip from camel message this way:

camelMessage.getHeaderAs("sourceAddr", String.class, getCamelContext());

I hope this will help

Daniel Collins

unread,
Jan 7, 2014, 2:34:38 PM1/7/14
to akka...@googlegroups.com
Fantastic, thank you Cedric this is exactly what I needed! I was able to successfully recode this in scala, and have included the stub code below for anyone else looking for the scala solution in the future as well.

object RemoteAddressConsumer {
    def apply(): Props = Props(classOf[RemoteAddressConsumer])

    class RemoteAddressProcessor extends Processor {
        import javax.servlet.http.HttpServletRequest
        override def process(exchange: Exchange) {
            val req:  HttpServletRequest = exchange.getIn.getBody(classOf[HttpServletRequest]);
            if(req!=null) exchange.getIn.setHeader("remoteAddr",req.getRemoteAddr());
        }
    }

    val mapper = new Mapper[RouteDefinition, ProcessorDefinition[_]]() {
        override def apply(rd: RouteDefinition): ProcessorDefinition[_] = rd.bean(classOf[RemoteAddressProcessor])
    }
}
class RemoteAddressConsumer extends Consumer {
    def endpointUri = "jetty:..."

    override def getRouteDefinitionHandler =  RemoteAddressConsumer.mapper

    def receive = {
        case msg: CamelMessage => {
            println("Message received from %s".format(msg.headers("remoteAddr")))
        }
    }
}

√iktor Ҡlang

unread,
Jan 7, 2014, 2:43:47 PM1/7/14
to Akka User List
Cool.

Happy hAkking!

Cheers,
Reply all
Reply to author
Forward
0 new messages