Apache Camel: Route from camel tomcat servlet to cxfbean component - apache-camel

Problem Description:
I am failing to route from my camel servlet to a cxfbean. Route initialization fails with the following error message:
"Failed to create route route1 at: >>> To[cxfbean:fooEndpoint] <<< in route:
Route[[From[servlet:///?servletName=BwsServlet]] -> [To[cxfb... because of Failed to resolve
endpoint: cxfbean://fooEndpoint due to: null".
The servlet starts fine without the cxfbean.
UPDATED: Please note that I intend to use a Camel Cxf Bean Component as opposed to a Camel Cxf Bean.
What I want to achieve:
I am running a camel servlet within Tomcat. I have a bean which implements my webservice interface (generated from WSDL by CXF). I want to process the XML message bodies before passing them on to this webservice bean. I would like to use cxf bean component as opposed to a cxf endpoint bean, since I do not want to have my cxf endpoint listen on a network port in addition to the already running camel servlet.
How my code looks like:
My camel-config.xml looks like this:
<bean id="bwsRouteBuilder" class="local.com.foo.BwsRouteBuilder"/>
<bean id="fooEndpoint" class="local.com.foo.FooBws"/>
<camel:camelContext id="bws">
<camel:routeBuilder ref="bwsRouteBuilder"/>
</camel:camelContext>
My route builder (written in Java DSL) looks like this:
public void configure() throws Exception {
from("servlet:///?servletName=BwsServlet")
// some processing of message here
.to("cxfbean:fooEndpoint");
}
UPDATED: Note the cxfbean URI format in the above code as defined here.
My web.xml looks like this:
<servlet>
<servlet-name>BwsServlet</servlet-name>
<servlet-class>org.apache.camel.component.servlet.CamelHttpTransportServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>BwsServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
camel-cxf is included as dependency in my pom.xml.
Where I looked at so far for help: I was following the documentation at Apache Camel cxfbean description and followed stackoverflow. I hope my question is not a no-brainer to answer, I am new to Camel.
Many thanks in advance for your thoughts

If you want to use a cxf bean you have to write "cxf:bean:fooEndpoint" in your route (you have forget : between cxf and bean).
public void configure() throws Exception {
from("servlet:///?servletName=BwsServlet")
// some processing of message here
.to("cxf:bean:fooEndpoint");
}

Related

OSGI service Call using Camel route

I get method not found exception when I try to connect/call OSGI service using camel route and I am not sure what logic I am missing here.
//Exception
Caused by: org.apache.camel.RuntimeCamelException: org.apache.camel.component.bean.MethodNotFoundException: Static method with name: getGreeting not found on class: com.test.api.Hello
//The below is the blueprint that exports osgi service
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<bean id="hello" class="com.test.HelloImpl"/>
<service ref="hello" interface="com.test.api.Hello"/>
</blueprint>
// Below is Java Interface and I did not include the java implementation code for interface here. but FYI, all method and class are declared as public
package com.test.api;
public interface Hello {
public String getGreeting();
}
//This below timer route is in Java DSL that is called by the route builder ref in the camel context and this camel context is defined inside blueprint
from("timer:foo?repeatCount=1")
.bean(com.test.api.Hello.class, "getGreeting")
.log("The message contains: ${body}")
I got the same exception when I tried executing this route in the same bundle where I export interface service and also I tried executing this timer route in another separate bundle by referencing the exported OSGI interface.
I am testing/executing these bundles in Red Hat Fuse server.
Request for thumbs down audience: please specify the reason before you thumbs down so that helps me to ask question in better way in future.
Thanks!!

How to use same CamelContext in multiple jar on the same war

I'm using the camel 2.16.2 and I need to use the one CamelContext across multiple jars as I need to have all the Camel Routers in to one CamelContext. So my war will have all those jars as maven artifacts.
Please let me know how do I handle above scenario?
Edit
Just to elaborate more on above question.
In my war myApp.war, I have initialized the CamelContext. There are three jars myApp1.jar, myApp2.jar and myApp3.jar. Each jar has it own routers defined separately.
How do I start the routers in each jar ?
Can I use the same CamelContext injected to each routers?
If I cannot handle through jars, is it possible to implement with multiple war (myApp1.war, myApp2.war and myApp3.war) and each war having different camelContext and communicate to those routers from the main war (myApp.war) ?
As other guys said, you can't use the same CamelContext across different Jars. Could you explain a little what you want to do?
IMHO what you want to do is use routes defined in different Jars. So for that you can define a Camel Context and add all the routes from different Jars. Of course your Camel-Context-JAR has to have access to all those jars.
<camel:camelContext id="camel5">
<camel:package>org.apache.camel.spring.example</camel:package>
</camel:camelContext>
Or class by class
<camelContext id="camel5" xmlns="http://camel.apache.org/schema/spring">
<routeBuilder ref="myBuilder" />
</camelContext>
<bean id="myBuilder" class="org.apache.camel.spring.example.test1.MyRouteBuilder"/>
Or if you are using CDI you can follow this great article https://dzone.com/articles/using-camel-routes-in-java-ee-components
Reference: http://camel.apache.org/spring.html
After doing some research found a way to implement this. Infact we can use the same CamelContext across different jars as all jars are in the same war (Web Container).
We can implement easily with Apache Camel 2.16.2 with camel CDI. If you're using wildfly to deploy your war then you may need to add the camel patch. Download the the wildfly 9.0.2 pach
Steps are Given Below.
In your war create a servlet or restService and Inject the camelContext.
#Inject
#ContextName("cdi-context")
private CamelContext camelctx;
Create a router in the jar with below annotation.
#Startup
#ApplicationScoped
public class MyJRouteBuilder extends RouteBuilder {
In Configure method add
#Override
public void configure() throws Exception {
from("direct:startTwo").routeId("MyJRouteBuilder")
.bean(new SomeBeanThree());
}
Create a BootStrap Class in your jar and add the Router
#Singleton
#Startup
public class BootStrap {
private CamelContext camelctx;
#PostConstruct
public void init() throws Exception {
camelctx.addRoutes(new MyJRouteBuilder());
}
Add your jar as a artifact in the war pom.xml. Once you deploy the war you can see MyJRouteBuilder is Registred in the cdi-context CamelContext. So now you can access your Router anywhere you want.
Hope this would useful anyone who has the same issue what I had.

Using blueprint as the Apache Camel DSL to describe routes in IBM Liberty

My goal is to get Camel running under IBM Liberty application server using OSGi and be able to describe the DSL (Domain Specific Language) routes in Blueprint. I am making progress and now have a Liberty environment with Camel installed and configured as OSGi bundles. When I write a Java DSL Camel app as an OSGi bundle, all works exactly as I might hope.
My last step is to be able to describe my camel routes in Blueprint. To that end I create a new OSGi bundle and defined a blueprint.xml that looks as follows:
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camelBlueprint="http://camel.apache.org/schema/blueprint"
xsi:schemaLocation="http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint-2.14.1.xsd">
<camelBlueprint:camelContext>
<camelBlueprint:route>
<camelBlueprint:from uri="file:c:/temp/in"/>
<camelBlueprint:to uri="file:c:/temp/out"/>
</camelBlueprint:route>
</camelBlueprint:camelContext>
</blueprint>
When I attempt to deploy this OSGi bundle, the IBM Liberty OSGi framework fails to deploy the application with the following errors:
[3/2/15 0:42:38:796 CST] 00000035 com.ibm.ws.app.manager.esa.internal.DeploySubsystemAction
A CWWKZ0403E: A management exception was generated when trying to install the application Camel1 into an OSGi framework. The error text from the OSGi framework is:
Resource does not exist: org.apache.aries.subsystem.core.archive.SubsystemContentRequirement:
namespace=osgi.identity, attributes={}, directives={filter=(&(osgi.identity=OSGITest1)(type=osgi.bundle)(version>=1.0.0))}, resource=org.apache.aries.subsystem.core.internal.SubsystemResource#7bc2d3bc
Unfortunately this is where I am now stumped and stuck. I believe that IBM Liberty uses Equinox as the OSGi platform and not Karaf but reading the Camel Blueprint docs I seem to understand that Apache Aries is required (which Liberty supplies and uses) and that Karaf isn't a dependency.
My MANIFEST.MF for my test bundle is:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: OSGITest1
Bundle-SymbolicName: OSGITest1
Bundle-Version: 1.0.0.qualifier
Bundle-Blueprint: OSGI-INF/blueprint/*.xml
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Export-Package: kolban.osgitest
Import-Package: org.apache.camel;version="2.14.1",
org.apache.camel.blueprint;version="2.14.1"
this message can occur if the resolver can't see the bundle, or there's something wrong with the bundle (typically with the Blueprint). If the bundle resolves ok when you remove the blueprint, then you need to look at what might be wrong in the blueprint. If this is the case, I would suspect you don't have the Camel blueprint namespace handler enabled in the runtime.
I hope this helps.
Regards, Graham.

Apache Camel - Deploy war application with RouteBuilder

Im new to Apache Camel, Please let me know How do we deploy a war with camel which activate routeBulder automatically?
I have configure in the applicationContext.xml
<camelContext xmlns="http://camel.apache.org/schema/spring" id="camel-3">
<routeBuilder ref="SearchProcessRoute" />
<bean id="SearchProcessRoute" class="camel.core.SearchProcessRouteBuilder" />
and the Route builder
public class SearchProcessRouteBuilder extends RouteBuilder {
#Override
public void configure() throws Exception {
// TODO Auto-generated method stub
from("activemq://search.queue")
.log("Process from the queue")
.bean("SearchProcessBean","ProcessData")
.to("activemq://search.process.queue");
}}
When I send a message to the search.queue it doesnt process anything?
Please let me know the proper way to deploy a web app with camel (Is there any sample application) and how do we solve the above issue?
PS. I was able to execute this as a standalone application. However, What I want to achieve is that connect from the standalone application to the activmq ("activemq://search.queue") which is deployed in the war and then the route (SearchProcessRouteBuilder) which is in the war activate automatically and that would process the queue. Then it will send the message to the other queue "activemq://search.process.queue".
Is this possible with Apache Camel, if So how we can achieve this?
you just need to add the following to the web.xml to bootstrap the Spring/Camel contexts
<!-- location of spring xml files -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- the listener that kick-starts Spring -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
see http://camel.apache.org/servlet-tomcat-example.html

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"));

Resources