Camel <packageScan> not working? - java

Using Camel 2.15.2, Spring 4.1.7.RELEASE.
Project: camel-example-cxf-tomcat
Route is created:
<bean id="myRoutes" class="org.apache.camel.example.cxf.CamelRoute"/>
<camelContext xmlns="http://camel.apache.org/schema/spring">
<routeBuilder ref="myRoutes"/>
</camelContext>
Route is not created:
<bean id="myRoutes" class="org.apache.camel.example.cxf.CamelRoute"/>
<camelContext xmlns="http://camel.apache.org/schema/spring">
<packageScan>
<package>org.apache.camel.example.cxf</package>
<excludes>*Hide*</excludes>
</packageScan>
</camelContext>

Issue because, camel package scan will ignore already instantiated classes. So remove your below code and try.
<bean id="myRoutes" class="org.apache.camel.example.cxf.CamelRoute"/>
Hope it helps!!

Please share the error you are getting while creating routes.
The <package> and <packageScan> will skip any classes which has already been created by Spring etc. So if you define a route builder as a spring bean tag then that class will be skipped. You can include those beans using <routeBuilder ref="theBeanId"/> or the <contextScan> feature.

Try to use
<packageScan>
<package>---specify package containing route here---
</package>
</packageScan>

Related

java.io.IOException: org.apache.camel.NoTypeConversionAvailableException

I am new to Apache Camel and Blueprint DSL and I am trying to marshal a bean to xml using jaxb but getting the following exception:
java.io.IOException: org.apache.camel.NoTypeConversionAvailableException: No type converter available to convert from type: com.test.rqst.InitiateReq to the required type: java.io.InputStream with value com.test.rqst.InitiateReq#681d07ed
My blueprint.xml is as follows
<bean id="testBean2" class="com.test.utility.StopTestDummy" />
<camelContext xmlns="http://camel.apache.org/schema/blueprint">
<route id="timerToLog">
<from uri="timer:foo?period=1000&repeatCount=1"/>
<bean id="testCastor" ref="testBean2"
method="setDummyValues" />
<marshal>
<jaxb prettyPrint="true" contextPath="com.scb.s2b.application.pymt.service.payment.stoppymt.rqst"/>
</marshal>
<log message="After Marshalling ${body}"/>
<to uri="mock:result"/>
</route>
</camelContext>
The method setDummyValues inside StopTestDummy class is creating the POJO(InitiateReq) as I wanted and returing the same. But I keep getting the error. What am I doing wrong.
Many Thanks.
Not sure this is the issue, but check these out.
First, are you marhsalling the correct class?
Exception says com.test.rqst.InitiateReq, while in your code you tell JAXB to marshal a different package: <jaxb contextPath="com.scb.s2b.application.pymt.service.payment.stoppymt.rqst"/>
Second, did you tell JAXB about InitiateReq class?
Create a file named jaxb.index in the same package and insert the name of the classes you want to marshal/unmarshal (only a line with InitiateReq in your case)

Akka Camel and Spring

I want to combine Akka, Apache Camel, Spring and do not know the way forward for leveraging the three things in the same project.
I was successfully able to
1. write some working code with akka, akka-camel extension and camel routes(Java DSL)
2. use camel and spring (use java DSL but spring for transactions and etc..)
Now I need to combine 1 and 2. Can anyone suggest me the simplest way to achieve this?
EDIT
Some say AKKA no longer supports Spring due to conflict in object instantiation as per the link below
Why spring integration doc for akka exists only for 1.3.1 but not for next versions
Also a similar question is there without a proper solution being presented but the post is about 2 years old
akka-camel 2.2.1 route definition using Spring XML
In one blog post (which I can't get hold of the link right now) a method has been described which is in summary, the actors are defined and used Akka way and what ever the processing Akka actors does to be wired using Spring. But there wasn't any solid example.
I imagine your #2 looks like this:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ctx="http://www.springframework.org/schema/context"
xmlns:camel="http://camel.apache.org/schema/spring"
xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd >
<!-- Camel route configuration -->
<camelContext id = "testCamelRouteContext" xmlns="http://camel.apache.org/schema/spring">
<route id="test_data_webservice">
<from uri="jetty:http://localhost:8888/myTestService"/>
<log logName="HTTP LOG" loggingLevel="INFO" message="HTTP REQUEST: ${in.header.testdata}"/>
<process ref="myTestService"/>
</route>
</camelContext>
<context:annotation-config />
<bean class="com.package.service" id="myTestService"/>
<bean id="genericDao" class="com.dao.Impl">
<property name="dataSource" ref="datasource" />
</bean>
<bean id="testingDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
datasource stuff
</bean>
</beans>
Is it possible that you can get this camel context through Akka? Something like.
Add in your Akka config:
akka.camel.context-provider="myNewContext"
New ContextProvider class:
class myNewContext extends ContextProvider{
override def getContext(system: ExtendedActorSystem): SpringCamelHybridContext
}
I am guessing this is where the bean injection collision between Spring and Akka could occur. I have never used Akka before so my answer is trivial but I wanted to see if I could provide some help to you.
Reviving an old thread.
akka-springctx-camel library is there to make your life painless to integrate Akka, Spring, Camel, CXF etc.
Add artifact :
<dependency>
<groupId>com.github.PuspenduBanerjee</groupId>
<artifactId>akka-springctx-camel</artifactId>
<version>1.0.0</version>
</dependency>
Add Camel Context Provider in Akka config:
akka.camel.context-provider=system.SpringCamelContextProvider
Get hold of ActorSystem :
implicit val system = SpringContextActorSystemProvider.create
Create a custom RouteBuilder[other way could be Akka Consumer]
class CustomRouteBuilder(system: ActorSystem, echoActor: ActorRef)
extends RouteBuilder {
def configure {
from("direct:testEP")
.routeId("test-route")
.to(echoActor)
}
Get Camel(Spring) Context and add routes to it:
val camel = CamelExtension(system)
camel.context.addRoutes(
new CustomRouteBuilder(system, system.actorOf(Props[EchoActor])))
This test case will give you a detailed idea: https://github.com/PuspenduBanerjee/akka-springctx-camel/blob/master/src/test/scala/AkkaSpringCtxTestSpec.scala

Separate route instances within single Camel context

I use Apache Camel module deployed inside ActiveMQ service.
Given I use Spring DSL and I have route definition ( implemented as routeContext) in the FilteringRouteContext.xml file (simplified):
<routeContext id="filteringRouteContext" xmlns="http://camel.apache.org/schema/spring">
<route id="myFilteringRoute">
<from uri="direct:filteringRoute"/>
<idempotentConsumer messageIdRepositoryRef="idempotentRepository" skipDuplicate="false">
<simple>${header.JMSType}</simple>
<filter>
<property>CamelDuplicateMessage</property>
<stop/>
</filter>
</idempotentConsumer>
</route>
</routeContext>
Next, I have configured Camel Context in other XML file (simplified):
<import resource="classpath:FilteringRouteContext.xml"/>
<camelContext xmlns="http://camel.apache.org/schema/spring">
<routeContextRef ref="filteringRouteContext"/>
<route id="myRoute1">
<from uri="activemq:topic:source1" />
<to uri="direct:filteringRoute" />
<to uri="activemq:topic:target1" />
</route>
<route id="myRoute2">
<from uri="activemq:topic:source2" />
<to uri="direct:filteringRoute" />
<to uri="activemq:topic:target2" />
</route>
<route id="myRoute3">
<from uri="activemq:topic:source3" />
<to uri="direct:filteringRoute" />
<to uri="activemq:topic:target3" />
</route>
</camelContext>
<bean id="idempotentRepository"
class="org.apache.camel.processor.idempotent.MemoryIdempotentRepository">
<property name="cacheSize" value="10"/>
</bean>
I would like to have shared route (with id=myFilteringRoute) from filteringRouteContext declared as, using IoC terminology, instance per dependency, so each route from single Camel Context (with id=myRoute1, myRoute2, myRoute3) should use it's own instance of that shared route (with id=myFilteringRoute), with separate internal state, bean instances, etc.
In other words, each route from Camel Context (with id=myRoute1, myRoute2, myRoute3) should not use the same instance of shared route (with id=myFilteringRoute), but should has its own completely separate instances (with completely separated internal states and bean instances )
Please consider that my shared route (with id=myFilteringRoute) may use more beans, which may have various scopes (singleton, prototype, request etc.).
My questions are: Can I achieve this goal using single Camel Context, or do I need to place my routes (with id=myRoute1, myRoute2, myRoute3) in separate Camel Contexts? What is the best solution of my problem?
Is there important performance impact If I use more than one Camel Contexts, and each context uses beans to communicate with ActiveMQ (org.apache.activemq.camel.component.ActiveMQComponent), or other beans that consume internal or system resources?
Or maybe it's better to resolve my problem by using Java DSL instead of Spring DSL?
Thank You.
Current Camel Spring DSL definitions are created by JAXB when it unmarshals the xml. This definitions help camel runtime to to build up processors and assemble them to route the message. In this way routeContextRef has nothing do with the scopes you mentioned.
But for the beans which you created by Spring with bean element, you can define the scopes if you like, and camel just grab it from Spring Application Context if there is bean reference in the Camel Spring DSL.
To answer you question, routeContextRef just give a way to share the route definition instance across the camel context, if you don't want share their instance you need to create the camel context in different spring application context which could hold the different instance of routeContext.
The answer is that Camel doesn't not provide an automatic mechanism for doing what you want to do. All routes in your example will share the same instance of idempotentRepository. The only solution is to provide a level of indirection.
For example, extend AbstractJdbcMessageIdRepository to provide your own implementation. This could then include the routeid in the look up to determine whether a message had already been processed.
Or you could have a set of repositories and look up which one to use from within the main idempotentRepository based on the route id.
Whatever you do, you'll need write code that uses the the route id of the outermost route to distinguish the messages.

Set attributes of ServletContext in Spring 3.2 MVC configuration

I'm stuck on a pretty simple task: how to set ServletContext attributes in Spring MVC 3.2 configuration?
I found that something similar can be done with ServletContextPropertyPlaceholderConfigurer, but from Spring 3.1 this is considered as deprecated:
"Deprecated. in Spring 3.1 in favor of PropertySourcesPlaceholderConfigurer in conjunction with StandardServletEnvironment."
This doesn't tell me much, since I don't know how to do it with StandardServletEnvironment.
Any suggestion?
You can use ServletContextAttributeExporter for this. Define a ServletContextAttributeExporter bean as below in your configuration file and set its attributes property to a map of key and value pairs that you want to put into ServletContext:
<bean class="org.springframework.web.context.support.ServletContextAttributeExporter">
<property name="attributes">
<map>
<entry key="myKey" value="1" />
</map>
</property>
</bean>
Create a *.properties file somewhere in your class path, e.g. /myprops.properties.
Add a property-placeholder to your context-config:
<context:property-placeholder location="myprops.properties"/>
or, if you are using java config:
#Configuration
#PropertySource("classpath:myprops.properties")
public class ApplicationConfiguration {
...
}

How do I inject a single property value into a string using spring 2.5.x?

I would really like to annotate a method with a reference to a single property in a property file for injection.
#Resource("${my.service.url}")
private String myServiceUrl;
Of course, this syntax does not work ;) Thats why I'm asking here.
I am aware that I can inject the full properties file, but that just seems excessive, I dont want the property file - I want the configured value.
Edit: I can only see PropertyPlaceholderConfigurer examples where XML is used to wire the property to the given field. I still cannot figure out how this can be achieved with an annotation ?
I know it has been a while since the original post but I have managed to stumble across a solution to this for spring 2.5.x
You can create instances of "String" beans in the spring xml configuration which can then be injected into the Annotated components
#Component
public class SomeCompent{
#Autowired(required=true
#Resource("someStringBeanId")
private String aProperty;
...
}
<beans ....>
<context:component-scan base-package="..."/>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
...
</bean>
<bean id="someStringId" class="java.lang.String" factory-method="valueOf">
<constructor-arg value="${place-holder}"/>
</bean>
</beans>
I've created a project which addresses this problem for Spring 2.5.*:
http://code.google.com/p/spring-property-annotations/
For Spring 3 you can use the #Value("${propery.key}") annotation.
There's a thread about this on the Spring forum. The short answer is that there's really no way to inject a single property using annotations.
I've heard that the support for using annotations will be improved in Spring 3.0, so it's likely this will be addressed soon.
you can do this if you use XML configuration. Just configure PropertyPlaceholderConfigurer and specify property value in configuration
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>classpath:com/foo/jdbc.properties</value>
</property>
</bean>
<bean ...>
<property name="myServiceUrl" value="${my.service.url}"/>
</bean>
You could try injecting value of property "my.service.url" to a filed in your bean.
Take a look at: http://static.springframework.org/spring/docs/2.5.x/reference/beans.html#beans-factory-placeholderconfigurer
HTH.

Categories

Resources