Using HTTP-based endpoints with Apache Camel

On a recent discussion, a partner was trying to use Apache ActiveMQ HTTP Transport Connectors to receive HTTP requests from a non-JMS Web application and asked me what I would think it could be a good approach to the use-case. Analyzing the use case, which needs a synchronous multi-step execution I suggested that they took a look in the Apache Camel Jetty component instead of Apache ActiveMQ and that was surprisingly easier to setup and maintain then the original approach.


While there is nothing wrong with the approach they thought about I think that Apache Camel would give them a more powerful setup to what they were looking for.


So, here is a sample configuration, that I created as a demo project, using Apache Camel Jetty component enabling HTTP endpoints.


In our Apache Camel route definition (using the Spring XML approach in this case) we'll have to define the Jetty endpoint similar to this:


<route id="Jetty_Sample">
        <from uri="jetty:http://localhost:8888/myBookService"/>

where we basically specify the address we'll be consuming HTTP requests. There are many options we can use to fine tuning the Jetty component but we'll keep it with only the required information for simplicity.

Then, the next step is going to be a regular approach to any other route we have developed so far. In this example, we're going to use a LOG component and then a custom Process pointing to a simple Java bean where we perform the processing of every request.

<log logName="HTTP LOG" loggingLevel="INFO" message="HTTP REQUEST: ${in.header.bookid}"/>

<process ref="myBookService"/>


The log component above will be displaying a header name called 'bookid' and then the Java bean (listed below) will be taking care of the request:

package com.fusesource.fusebyexample;

import org.apache.camel.Processor;
import org.apache.camel.Exchange;

public class myBookService implements Processor {
    public void process(Exchange exchange) throws Exception {
        // Grab the booked header value
        String bookId = (String) exchange.getIn().getHeader("bookid");
        // send a html response
        exchange.getOut().setBody("<html><body>Book " + bookId + " is Camel in Action.</body></html>");
    }
} 

The last thing we need to add to our Apache Camel context file is the bean definition which could be simply like the line below:

<bean class="com.fusesource.fusebyexample.myBookService" id="myBookService"/>

That's all we need... To test the integration use case described above, we can simply run the Camel route, open any web browser and hit the following URL:

http://localhost:8888/myBookService?bookid=91942

where the Camel route will log the following in the console:

HTTP LOG                       INFO  HTTP REQUEST: 91942

and the web browser will display the result of the Java bean processing with the following:


If you want to use a simple HTML form, here is something to easily test the Camel route...

<html>
<body>
<form action="http://localhost:8888/myBookService">
Book ID: <input text name="bookId"/>
<input type="submit" value="Submit">
</form>
</body>
</html>

I've also included the test HTML form on the source code package of this configuration available here:


Enjoy the ride!


Comments

  1. Hi Marcelo,
    I have followed the same steps you mentioned above but hitting the url then getting the message on browser as "unable to connect"
    please help what did i wrong?

    ReplyDelete
  2. Hi Manjesh,
    Did you start the Camel route successfully? That "unable to connect" message may indicate that you could not hit the server at the of the request.
    -Marcelo

    ReplyDelete
  3. Hi Marcelo, Thanks a lot for replying so quickly.
    I am hitting the url on browser after starting the server by hitting "activemq.bat"
    Please let me know how to start Camel route????
    i think that it is something else...need to start..

    ReplyDelete
  4. Ahh ok... so here is the thing, if you don't have the Camel route configured in the activemq.xml file you would never start the Jetty server. The way this example was created you don't need an instance of ActiveMQ but rather just run the Camel route as described in the Readme.txt file. Open a command prompt in the same directory you have the pom.xml file and try running the following command: mvn camel:run. I assume you have Maven configured on your machine. That's the easiest way of running this sample. Take care...

    ReplyDelete
  5. hi Marcelo Jabali,
    I have the scenario which is quite opposite to the above sample in which i need to hit the rest service which is running on other server using jetty component in apache camel .
    PLZ help me in doing that......

    ReplyDelete
    Replies
    1. From the little description I imagine you want to configure a "to clause instead of a "from" clause on your Camel route.

      Delete
    2. Thanks Marcelo Jabali for replying me , actually my scenario is just hit a rest service(NOPAYLOAD). this is the code that I've wriiten.g
      from("direct:start")
      .to("jetty:http://localhost:7777/MyRestFull/rest/calci/hit");

      I would like to know is it write or wrong . and when i'm executing this no hit's were found on the server side.PLZ correct if i'm wrong.

      Delete
    3. Have a look at the Jetty Camel component page where there is a consumer and a producer sample available to you --> http://camel.apache.org/jetty.html

      Delete
    4. Thanks Marcelo Jabali,
      i've followed your suggestions and solved that issue and i've one more doubt .
      can I transfer data from a bean method to jetty component.my code is as follows
      from("timer://start?period=10000")
      .to("class:jetty.MyBean?method=onMarch") .to("jetty:http://localhost:7777/MyRestFull/rest/database/insert?name=.........-----........");
      wher i'm sending the return value of bean method(onMarch) as queryparam to the jetty url.

      Delete
    5. Manoj, I recommend you to take a look at Camel Bean (http://camel.apache.org/bean.html) and Bean-Binding (http://camel.apache.org/bean-binding.html) as they cover what you're trying to do.

      Delete
  6. This comment has been removed by the author.

    ReplyDelete
  7. Hey!
    Great tutorial by the way. I keep getting: "No context on this server matched or handled this request. I am going here for my URL: "http://localhost:8080/MyRoute?bookid=9142". My Eclipse is defaulted at 8080 as localhost, so I'm going to that when I'm running my path.

    ReplyDelete
    Replies
    1. The "from" line in the Camel route points to the hostname and port number you should be using. If you use localhost and 8888 then that's where you should go to. If you have changed the Jetty component in the Camel route then point to whatever you have changed to.

      Delete
    2. Thanks for the super quick response... however, I'm still getting an error.

      This is what I have...

      In MyRoute.java:
      https://www.dropbox.com/s/hdi92jeiad2mott/myRoute.PNG?dl=0

      In my Camel-Context:
      https://www.dropbox.com/s/j8q1h32nmquyea8/camel-context.PNG?dl=0

      Thank you much.

      Delete
  8. Hello Marcelo :)
    Thank you very much! This article helped me to solve one issue connected with non-JMS web app.

    ReplyDelete
    Replies
    1. Thanks for the feedback. Good luck to you.

      Delete
  9. Very useful indeed. Thanks Marcelo.

    /Kasun

    ReplyDelete
  10. Ultimez Technology is one of the best web design company India, get innovative services from us.

    Web Design company in Hubli | web designing in Hubli | SEO company in Hubli

    ReplyDelete

Post a Comment

Popular posts from this blog

Calling Web Services with Apache Camel

How to Declare Variables in MS-SQL Server Management Studio