How to use same CamelContext in multiple jar on the same war - apache-camel

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.

Related

CamelContext apache camel

is it necessary to create a camelcontext like this ? and the use the start() and stop() methods ?
CamelContext camelContext = new DefaultCamelContext();
Because even when I don't create a camel context and not use start() and stop(), my route works and the files are copied from one folder to another.
from("file:C:/Users/user1/Desktop/in").process(new MyProcessor()).to("file:C:/Users/user1/Desktop/out");
So why in some tutos, they say that it is necessary to create camelcontext ?
if you're using quarkus vs spring boot you don't need to explicitly start camel routes . If you do it only with java without using any framework, you should add these routes to the context and start them later.These frameworks start and stop for you in the background .

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!!

Camel route should be annotated with component or configuration

I have camel route which basically used to move files from source to destination as below
public class SimpleRouteBuilder extends RouteBuilder {
#Override
public void configure() throws Exception {
from("file:C:/inputFolder?noop=true").to("file:C:/outputFolder");
}
}
Question is which annotation(#component or #Configuration) should be used to load this route
If you are using Spring or Spring Boot etc then it should be #Component which ensures the class is enlisted into the spring bean registry, which Camel then scans for RouteBuilder classes and automatic adds to the CamelContext.
Mind that Spring Boot has some classpaths it only scans (I think its the package of the main class and sub packages), so if you put it inside other packages outside that, you may need to configure spring boot to scan for other packages.

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

How can I configure the JAX-RS base path in TomEE+?

I have a WAR with some JAX-RS services, deployed into TomEE Plus. Given a service annotated with #Path("myservice"), TomEE+ publishes it to localhost:8080/mywebapp/myservice.
However, that also makes accessing a JSP at localhost:8080/mywebapp/index.jsp impossible - JAXRSInInterceptor complains that No root resource matching request path has been found, Relative Path: /index.jsp.
So I would like to configure a path prefix api to all services, which changes the myservice URL to localhost:8080/mywebapp/api/myservice. Doing so would be trivial if I had configured CXF on my own (with or without Spring), because I could simply change the URL pattern of the CXF Servlet - but I am relying on the default settings where I don't configure anything besides the annotations. So how do I do that in this case?
Note that I don't want to alter the #Path annotations to include the prefix, because that does not fix the issue with the JSP.
Create an extension of javax.ws.rs.core.Application and annotate it with #ApplicationPath where value would be api in your case:
#ApplicationPath("/api")
public class MyApplication extends Application {
#Override
public Set<Class<?>> getClasses() {
final Set<Class<?>> classes = new HashSet<Class<?>>();
// register root resource
classes.add(MyServiceResource.class);
return classes;
}
}
This way a Servlet 3 container would find your application and map your resource to /mywebapp/api/myservice while making your web resources (.jsp) available at /mywebapp.
TomEE trunk supports these configurations: cxf.jaxrs.staticSubresourceResolution & cxf.jaxrs.static-resources-list
but the #ApplicationPath is the more relevant solution IMO
Using -Dopenejb.webservice.old-deployment=true can help too in some cases

Resources