2

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 /testand 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?

lostWasIt
  • 45
  • 5

1 Answers1

1

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.

ShellDragon
  • 1,712
  • 2
  • 12
  • 24
  • Exactly what I needed! If I understand properly, I could also add multiple endpoints/routes by adding more `` blocks in the .xml file. – lostWasIt Feb 17 '20 at 09:11
  • For any people that use Java 8, you will need to adjust the pom file to compile the project: https://stackoverflow.com/a/42525941/4761457 – lostWasIt Feb 17 '20 at 09:46
  • 1
    Oh sorry! I forgot to mention that my target was JVM 11. To add additional servlet endpoints under `http://server//camel`, you may just add new Servlet routes in the `DefaultRouteBuilder ` class. Another endpoint like `from("servlet:hola?matchOnUriPrefix=true")` should do the trick. – ShellDragon Feb 17 '20 at 12:24