Camel - Using beans available in jar - spring

I am using Spring's Application context for bean registry. I will be dependent on external jars for some services, which will be a part of routes.
Is there any way to let camel auto-register the beans that are available in the jar?

No, but you can call any java class from Camel using its bean component. You can specify a class name, and a method to invoke.
You can use the beanType attribute
<bean beanType="com.foo.MyClass" method="someNameHere"/>
Or in an uri
<to uri="bean:com.foo.MyClass?method=someNameHere"/>

Related

Osgi Inject bean into Activator

I have 3 classes , one is Activator and two others, 'mysqlConfiguration' and 'BinaryLogListner' where 'mysqlConfiguration' is injected into 'BinaryLogListner' using blueprint.
This is my blueprint (the injection part):
<bean id="binaryLogListnerBean" class="cdc.mysql.BinaryLogListner">
<property name="mysqlConfiguration" ref="configManagementMysql"></property>
</bean>
I want to start the BinaryLogListner when the bundle starts , so I instanciated it from the Activator class with :
BinaryLogListner binaryLogListner = new BinaryLogListner();
When i try to use 'mysqlConfiguration' which is injected into 'BinaryLogListner' I will get a null pointer Exception.
I want to know how to inject a bean into an activator, is this possible ?
Any thougts how to start beans in these situations?
In the Activator you instantiate the class using new BinaryLogListner(). So you simply get the plain class without any blueprint injects. These injects only work when the bean instance is created by blueprint.
Instead of an Activator you should simply use an init-method on any blueprint bean to react on the (blueprint) activation of the bundle.
Generally whenever you use blueprint in a bundle you should not also use an Activator.

How can I pass certain properties to the Spring context through servlet params?

So we decided to deploy our application no more as a war on the usual tomcat, but from an embedded jetty. My app uses context:property-placeholder to resolve properties from a file. Now I'd need to pass some (or all) properties programatically before starting jetty. Is there a way that allows me to set some properties by code, before running jetty, instead of relying on the .properties file? For example as Servlet params?
You can use ServletContextPropertyPlaceholderConfigurer. This PropertyPlaceholderConfigurer extract the properties from the servlet context init params.
From Spring Javadocs:
Subclass of PropertyPlaceholderConfigurer that resolves placeholders as ServletContext init parameters (that is, web.xml context-param entries).
But this class is deprecated from Spring version 3.1.
From version 3.1 you don't need to use any special configuration because all Web Based servlet context use the class org.springframework.web.context.support.StandardServletEnvironment that resolve properties from servlet context params by default.

How to inject a Spring bean in to Camel DefultProducer

I have written a camel component by extending DefaultComponent and also have the associative classes implemetation for endpoint, consumer, producer. My producer is extending the camel DefaultProducer and I want to inject a spring bean inside this class, so that whenever a route will be executed like
<route id="myRoute"><from uri="file://inbox"/><to uri="myComp://outbox"/>
I will be able to get the file from the file system and store it into database. For storing the file into the DB I have a service class instantiated by the spring container, but whenever I inject that bean into MyProducer we are getting null.
I recongnized the problem was not about Camel, it is related to the spring and I was injecting the bean in a wrong way. I resolved the problem by implementing the ApplicationContextAware interface into my helper class and storing the spring context as static variable and with the help of this helper class I am able to get spring bean inside MyProducer class. Thanks for spring ApplicationContextAware interface.

akka-camel 2.2.1 route definition using Spring XML

I am using akka-camel 2.2.1 and need to configure routes to and away from Consumer and Producer actors, respectively. I am currently defining routes and adding them to the internal Camel context within the CamelExtension programmatically like so:
camel.context.addRoutes(new RouteBuilder {
def configure() = {
from("file:/tmp?include=whatever.*.log&noop=true&sendEmptyMessageWhenIdle=true")
.split(body(classOf[String]).tokenize("\n"))
.streaming()
.to("seda:input-route")
from("seda:update-route")
.to("bean:db-update-bean?method=process")
}})
I have an Actor that extends Consumer which reads from "seda:input-route" via its endPointUri, and another Actor that extends Producer that writes to "seda:update-route". The "db-update-bean" in defined in a Spring applicationContext.xml like so:
<bean id="db-update-bean" class="nz.co.whatever.DBUpdate">
<constructor-arg ref="jdbcTemplate"/>
<constructor-arg value="some_other_constructor_arg"/>
</bean>
The Spring context is loaded and started in a supervisor Actor started by akka.Main. However (and understandably), Camel is unaware of this Spring context, and thus went to great lengths to inform me that it had no clue what the "db-update-bean" was:
2013-10-11 08:55:09,614 [SedaConsumer ] WARN Error processing exchange. Exchange[Message: 1378642997698,27684,true,57.000000,0.750000,97]. Caused by:
[org.apache.camel.NoSuchBeanException - No bean could be found in the registry for: db-update-bean]
Of course, I could programmatically add the components to the akka-provided CamelContext, or else do something like this:
from("seda:update-route")
.bean(new DBUpdate(jdbcTemplate, "gps_temp_status"), "process")
but I would rather use Spring to define beans. Clearly, the CamelExtension needs to use the Spring-defined CamelContext rather than creating one of its own.
Furthermore, and more importantly, I would like to externalize the definition of the Camel routes into the same applicationContext.xml within a <CamelContext/> tag. Accoring to articles such as https://weblogs.java.net/blog/manningpubs/archive/2013/02/13/akka-and-camel, it seems the way to do so is to instantiate a "camel-service" bean and inject the Spring-defined CamelContext as so:
<camel:camelContext id="camelContext">
</camel:camelContext>
<akka:camel-service id="camelService">
<akka:camel-context ref="camelContext" />
</akka:camel-service>
Here is where the wheels come off. According to Roland Kuhn's reply in Why spring integration doc for akka exists only for 1.3.1 but not for next versions, the akka-spring library is not included in Akka 2.2.1, and thus there is no Spring namespace handler for akka, and I'm unable to instantiate this camel-service bean. Though not for lack of trying. Or cursing.
And so (finally), the question: How does one define Camel routes in Spring XML whose endpoints can be used by Consumer or Producer Actors using akka-camel 2.2.1 without akka-spring? Does one instantiate a Factory bean that produces a CamelService with a CamelContext injected or some other such witchcraft? Secondarily (but related) how can I use Spring to instantiate beans to be referenced in camel routes if I am forced to define them via a RouteBuilder?
Thanks in advance.

Recommended way to access Spring beans in Apache Tomcat webapp?

I'm developing a web application on Apache Tomcat 6 with Hibernate and Spring, I'm using different XML configuration files to define my Spring beans (like the Hibernate DAO, Quartz scheduler and some other stuff). All these files are loaded at Tomcat start up via web.xml (ContextLoaderListener).
Now I'm not sure what is the recommended way to get access to my beans.
Should I write on class which provides the BeanFactory for all classes which should use a bean, or is it the better way to load the BeanFactory in each class.
BeanFactory bf = (BeanFactory) ContextLoader.getCurrentWebApplicationContext();
One of the core ideas of the spring framework is to minimize dependencies between classes. You'll get the most benefit by using this concept throughout your whole project. Each and every backend object should be defined as bean and can therefore use the dependency injection automatism.
If some of your Beans need to access the ApplicationContext directly (eg for requesting all Beans implementing some marker interface) you can implement the ApplicationContextAware interface, so still no factory is needed.
Use dependency injection instead. Create getters & setters in each controller class, and use your *-servlet.xml to inject the required beans via the <property> tag. No factory needed!

Resources