Issue
The past few days I've been searching how to do the below without having any knowledge in Tomcat or Camel and I'm surprised I haven't found any good resources on this:
Make a .war file that will be deployed into Tomcat (e.g. from Manager App) which will accept a request on a given URI /test
and will forward the request to an internal service in PHP which runs on localhost:8222/index.php?q=test
.
I have managed to have a working example of forwarding a request to a different url by building on top of the camel-archetype-java
and the router looks like this:
package camelinaction;
import org.apache.camel.builder.RouteBuilder;
public class MyRouteBuilder extends RouteBuilder {
public void configure() {
String targetUrl = "https://another.service.com/api/test";
from("jetty:http://127.0.0.1:25566/test?matchOnUriPrefix=true")
.to("jetty:" + targetUrl + "?bridgeEndpoint=true&throwExceptionOnFailure=false");
}
}
and I have managed also to create a .war file from the camel-example-servlet-tomcat
example that in Camel and deploy it successfully in tomcat. That example doesn't have any Java code though in its project folder and is consisted basically from just .xml files and a .html page which is served by the Camel servlet when requests the related servlet path which is served by tomcat.
The basic xml of that project looks like below:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel="http://camel.apache.org/schema/spring"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route id="helloRoute">
<!-- incoming requests from the servlet is routed -->
<from uri="servlet:hello"/>
<choice>
<when>
<!-- is there a header with the key name? -->
<header>name</header>
<!-- yes so return back a message to the user -->
<transform>
<simple>Hi I am ${sysenv.HOSTNAME}. Hello ${header.name} how are you today?</simple>
</transform>
</when>
<otherwise>
<!-- if no name parameter then output a syntax to the user -->
<transform>
<constant>Add a name parameter to uri, eg ?name=foo</constant>
</transform>
</otherwise>
</choice>
</route>
</camelContext>
</beans>
How would someone would combine the two examples/functionalities to achieve the end goal of having a request that comes from tomcat to be forwarded with camel to a different endpoint?
Solution
Since you are already deploying this WAR in a servlet container that can handle HTTP, there is no need to use camel-jetty component, but could leverage on camel-servlet and camel-servlet-listener components.
Your first example uses Camel's Java DSL and the second one follows XML DSL, it may be a bit intimidating at the first go. I couldn't find any samples that combine the specific scenario so I have hacked together a quick demo that could be deployed in a servlet container and could route calls to another HTTP Service. It is a tiny demo and would need some modifications. I tested it with jetty but haven't tried throwing it at a Tomcat.
In the web.xml file, the following section controls the context.
<!-- Camel servlet mapping -->
<servlet-mapping>
<servlet-name>CamelServlet</servlet-name>
<url-pattern>/camel/*</url-pattern>
</servlet-mapping>
There's only one java file, the route configuration, as shown below
public class DefaultRouteBuilder extends RouteBuilder {
@Override
public void configure() throws Exception {
from("servlet:hello?matchOnUriPrefix=true")
.routeId("HTTP Bridging Route")
.log("Request: ${in.header."+ Exchange.HTTP_METHOD +"} to ${in.header."+ Exchange.HTTP_URI +"}")
.to("https://another.service.com?bridgeEndpoint=true");
}
}
Once the servelet starts, you can access the HTTP resource, backed by camel at http://server/<context root>/camel/hello
I hope it helps you to get going.
Answered By - ShellDragon