Start apache camel route when client request made - apache-camel

I have apache camel application where huge number of routes are available and want to start it only when http request are made for them. For example, have two routes as mentioned in the documentation where autoStartup is set to false
<camelContext id="myCamel" xmlns="http://camel.apache.org/schema/spring"
autoStartup="false">
<route>
<from uri="direct:foo"/>
<to uri="mock:foo"/>
</route>
<route>
<from uri="direct:bar"/>
<to uri="mock:bar"/>
</route>
</camelContext>
I want to start the routes when the request are made for them. For example, when /rest/foo request made, I want to start the corresponding route and allow the corresponding route to serve the request.
The documentation says, we can start the route by using spring ApplicationContext.
ApplicationContext ac = ...
CamelContext camel = ac.getBean("myCamel", CamelContext.class);
// now start all the routes
camel.getRouteController().startAllRoutes();
should I write a filter program to intercept all http request and get hold spring context to start the corresponding route? or where do I have to put the above code to start the route exactly. can someone help please.

Related

How to refer external jar route from Camel context file

I have project A which has below simple route logrouteTest.xml
<routeContext id="CommonLogRoutes" xmlns="http://camel.apache.org/schema/spring">
<route id="logRoute">
<from id="_NSDL_PAN" uri="seda:MyLogRoute"/>
<convertBodyTo id="_convertBodyTo1" type="java.lang.String"/>
<log message="my received body : ${body}"/>
</route>
</routeContext>
I composed this project into JAR.
In my project B I have imported the above jar and trying to refer the Project A route like this
<import resource="classpath:com/tcl/Testjar/logrouteTest.xml"/>
Error
I am getting the below error
java.io.FileNotFoundException: class path resource [com/tcl/Testjar/logrouteTest.xml] cannot be opened because it does not exist
Is there any way to refer the external project camel route from current project route without deploying project A.
Note : I am looking for option to use Project A as ESB library

Apache Camel getUri of ToDefinition in version >= 2.16.0

i have jsut upgraded my camel version and some functionality that was working before version 2.16.0 is now broken, I used to be able to get the URI for a toDefinition that replaced a placeholder, having just upgraded, this now doesnt replace the placeholder.
Code example is as follows:
<propertyPlaceholder id="properties" location="config.properties" />
<route>
<from uri="direct:input" />
<to uri="mq:queue:{{MY_PLACEHOLDER}}" />
</route>
config.properties
MY_PLACEHOLDER=FOO
Camel version 2.15.5
toDefinition.getUri() // equals mq:queue:FOO
Camel version 2.16.0
toDefinition.getUri() // equals mq:queue:{{MY_PLACEHOLDER}}
Any ideas?
Yes that is how its intended to be. The model is the model as it was designed (in this case with placeholder value).
The resolved uri is when Camel startup and runs the routes. So you can take that uri, and ask Camel to resolve, there is an API on CamelContext for that resolvePropertyPlaceholders
http://static.javadoc.io/org.apache.camel/camel-core/2.18.2/org/apache/camel/CamelContext.html#resolvePropertyPlaceholders-java.lang.String-

InvocationTargetException while hitting rest service in camel route

I am using camel vs2.9.0 in my project and trying to hit a Rest service.
My route is as mentioned below:
<route>
<from uri="direct:restRoute"/>
<bean ref="finalProcess"/>
<setHeader headerName="CamelHttpMethod"><constant>POST</constant></setHeader>
<to uri="http rest service url here"/>
finalProcess is just a bean in which I am doing like this :
System.out.println(exchange.getIn().toString());
I am able to put a json request on the route which gets printed on the above sysout code
, but I am getting following error when it reaches to uri="" step.
WARNING : WebApplicationException has been caught : java.lang.reflect.InvocationTargetException

Translation XML information to Java - Apache Camel

This is the example that is bundled with apache camel binaries
<route>
<!-- 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>Hello ${header.name} how are you?</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>
How to translate this to Java
Am a beginner in camel, and some how came up to this
CamelContext context = new DefaultCamelContext();
context.addRoutes(new RouteBuilder(){
public void configure(){
from("servlet://hello").transform().....
}
});
But dont know how to proceed further...
If you want to port it over to java without any XML (spring that is) you can't (easily) use the servlet component.
Just porting the route will be like:
from("servlet:///hello")
.choice()
.when()
.header("name")
.transform(simple("Hello ${header.name} how are you?"))
.otherwise()
.transform(constant("Add a name parameter to uri, eg ?name=foo"));
It should work in the spring example (or any spring web app), just replacing the <route> in the <CamelContext> with <routeBuilder ref="demoRoute"> given you have defined your route as a spring bean (<bean id="demoRoute" class="org.example.demo.DemoRoute">).
However, I guess you want to do this in plain java (no spring, no xml, no webapp). You could go with the Jetty component. The difference being that Camel then will start the servlet container, instead of the servlet container starting Camel. No difference for this simple example though.
I suggest you start out with a Maven archetype to get the skeleton up
e.g. mvn archetype:generate then choose org.apache.camel.archetypes:camel-archetype-java (Creates a new Camel project using Java DSL.)
Well, you don't need the maven archetype if you have your own java application and have the thread keep running. Then you should do fine with your approach. The maven archetype is however very good for training purposes.
You then need to add a dependency to Jetty (camel-jetty.jar) (read more here).
The actual route would be exactly the same except the first row: from("jetty:http://localhost:8080/camel/hello")
Nice and easy.
Try this one:
from("servlet://hello")
.choice()
.when(header("name").isNotNull()).transform(simple("Hello ${header.name} how are you?"))
.otherwise().transform(constant("Add a name parameter to uri, eg ?name=foo"));

Getting org.apache.camel.component.http.HttpOperationFailedException with Status Code 405

I am running servicemix 4.4.1. I am trying to make a http call to a website by using camel-http4. No matter which website I try to invoke, I keep getting this error:
org.apache.camel.RuntimeCamelException: org.apache.camel.component.http.HttpOperationFailedException: HTTP operation failed invoking http://servicemix.apache.org/downloads/servicemix-4.4.0.html with statusCode: 405
Here is my code snippet:
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="activemq://events1"/>
<setHeader headerName="CamelHttpMethod">
<constant>POST</constant>
</setHeader>
<to uri="http://servicemix.apache.org/downloads/servicemix-4.4.0.html"/>
<to uri="log:events"/>
</route>
</camelContext>
I have tried a number of sites and tried using different http methods (post vs get), and I keep getting the same error. Any idea? Thanks in advance.
The website you specified is no target of a form. So most likely it will only allow GET requests not POST. So try to set the CamelHttpMethod to GET.
Btw. what do you want to achieve with your route? If you want to send the activeMQ message to the website then POST is ok but you have to use a website that accepts POST.
You could achieve that by defining your own route to receive the request.
Then you can send to that url in the first route.
I checked this;
problem solved by set option 'bridgeEndpoint';
You are setting the http endpoint to be bridgeEndpoint which means the request url will be updated with request URI.
<route>
<from uri="-------"/>
<to uri="jetty://http://localhost:9090/my.html?bridgeEndpoint=true"/
<to uri="log:events"/>
</route>

Resources