How load multiple camel context in spring - spring

I want to upload multiple camel context files ( camel-context.xml ; camel-context2.xml ) in spring java application. I am trying the below way to upload files. But only single file gets loaded.
#SpringBootApplication
#ImportResource({"classpath:camel*.xml"})
In the below snapshot in console blue marked gives success response , red shows error.
Note : I have tried this approach as well . Didnt workout.
#ImportResource("camel-context.xml", "camel-context2.xml")

https://camel.apache.org/manual/latest/camel-3-migration-guide.html#_multiple_camelcontexts_per_application_not_supported
Support for multiple CamelContexts has been removed and only 1 CamelContext per deployment is supported. The latter was not recommended anyway and was also not 100% implemented (for example in camel-cdi). For Camel 3 only 1 CamelContext per deployment is recommended and supported.
But you can do the following way of separating your route configurations as this is still one camel context. https://camel.apache.org/manual/latest/faq/how-do-i-import-routes-from-other-xml-files.html
File 1:
<beans ....">
<routeContext id="myCoolRoutes" xmlns="http://camel.apache.org/schema/spring">
<route id="cool">
<from uri="direct:start"/>
<to uri="mock:result"/>
</route>
<route id="bar">
<from uri="direct:bar"/>
<to uri="mock:bar"/>
</route>
</routeContext>
</beans>
File 2: (File 1 is imported)
<beans ..>
<import resource="myCoolRoutes.xml"/>
<camelContext xmlns="http://camel.apache.org/schema/spring">
<routeContextRef ref="myCoolRoutes"/>
<route id="inside">
<from uri="direct:inside"/>
<to uri="mock:inside"/>
</route>
</camelContext>
</beans>

Related

Jackrabbit repository could not be accessed from karaf container

I am trying to access a jackrabbit repository through rmi from karaf container
I developped a camel route which save a file into jackrabbit repository
<bean id="repository"
class="org.apache.jackrabbit.rmi.repository.URLRemoteRepository">
<argument value="http://localhost:8020/rmi" />
</bean>
<camelContext id="blueprintContext" trace="false"
xmlns="http://camel.apache.org/schema/blueprint">
<route id="depotfichiersurjcr">
<from uri="file:/C:/data?recursive=false&noop=true" />
<!-- log message="message1 ${body}"/ -->
<setHeader headerName="CamelJcrNodeName">
<constant>node</constant>
</setHeader>
<setHeader headerName="my.contents.property">
<simple>${bodyAs(String)}</simple>
<!-- constant>content</constant -->
</setHeader>
<setBody>
<constant></constant>
</setBody>
<to uri="jcr://admin:admin#repository/default?deep=true&eventTypes=3&noLocal=false" />
<to uri="direct:a" />
</route>
</camelContext>
the route works fine with mvn camel:run
the same route doesnt work inside the karaf container , i got :
javax.jcr.RepositoryException: Remote repository not found: The resource at http://localhost:8020/rmi could not be retrieved
at org.apache.jackrabbit.rmi.repository.URLRemoteRepositoryFactory.getRemoteRepository(URLRemoteRepositoryFactory.java:84)[1626:org.apache.jackrabbit.jackrabbit-jcr-rmi:2.6.2]
at org.apache.jackrabbit.rmi.repository.AbstractRemoteRepositoryFactory.getRepository(AbstractRemoteRepositoryFactory.java:57)[1626:org.apache.jackrabbit.jackrabbit-jcr-rmi:2.6.2]
at org.apache.jackrabbit.rmi.repository.ProxyRepository.login(ProxyRepository.java:199)[1626:org.apache.jackrabbit.jackrabbit-jcr-rmi:2.6.2]
at org.apache.jackrabbit.rmi.repository.ProxyRepository.login(ProxyRepository.java:233)[1626:org.apache.jackrabbit.jackrabbit-jcr-rmi:2.6.2]
at com.sagemcom.Content.process(Content.java:21)[1618:content:0.0.1.SNAPSHOT]
at org.apache.camel.processor.DelegateSyncProcessor.process(DelegateSyncProcessor.java:63)[171:org.apache.camel.camel-core:2.13.2]
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:72)[171:org.apache.camel.camel-core:2.13.2]
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:398)[171:org.apache.camel.camel-core:2.13.2]
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)[171:org.apache.camel.camel-core:2.13.2]
at org.apache.camel.processor.Pipeline.process(Pipeline.java:118)[171:org.apache.camel.camel-core:2.13.2]
at org.apache.camel.processor.Pipeline.process(Pipeline.java:80)[171:org.apache.camel.camel-core:2.13.2]
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)[171:org.apache.camel.camel-core:2.13.2]
at org.apache.camel.component.timer.TimerConsumer.sendTimerExchange(TimerConsumer.java:157)[171:org.apache.camel.camel-core:2.13.2]
at org.apache.camel.component.timer.TimerConsumer$1.run(TimerConsumer.java:68)[171:org.apache.camel.camel-core:2.13.2]
at java.util.TimerThread.mainLoop(Timer.java:555)[:1.7.0_75]
at java.util.TimerThread.run(Timer.java:505)[:1.7.0_75]
Caused by: java.io.IOException: Server returned HTTP response code: 503 for URL: http://localhost:8020/rmi
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1627)[:1.7.0_75]
at java.net.URL.openStream(URL.java:1037)[:1.7.0_75]
at org.apache.jackrabbit.rmi.repository.URLRemoteRepositoryFactory.getRemoteRepository(URLRemoteRepositoryFactory.java:61)[1626:org.apache.jackrabbit.jackrabbit-jcr-rmi:2.6.2]
... 15 more
is there any specific configurations that should be done to let the karaf container see the jackrabbit url, any suggestion will be welcome , Thanks .
In the case of the testcase the configuration is from the baseclass, which may need to be added to camel context.
Here's an example configuration from a camel example for the rmi:
<bean id="rmiServer" class="java.rmi.registry.LocateRegistry" factory-method="createRegistry">
<constructor-arg index="0" value="${port}"/>
</bean>
<camelContext xmlns="http://camel.apache.org/schema/spring" depends-on="rmiServer">
<endpoint id="rmiService"
uri="rmi://localhost:${port}/helloServiceBean?remoteInterfaces=org.apache.camel.example.osgi.HelloService"/>
<!-- expose a RMI service as a Camel route -->
<camel:route>
<from ref="rmiService"/>
<to uri="log:Incoming request on RMI"/>
<to uri="bean:helloServiceBean"/>
</camel:route> </camelContext>
Now this is typically needed if you're using rmi.
In the case that you have just described, we need the JndiRegistry.
Can you try adding the following to the camel context
<bean id="registry" class="org.apache.camel.impl.JndiRegistry"/>
In the case of the JCR Jackrabbit try the following bean configuration:
<bean id="repository" class="org.apache.jackrabbit.rmi.repository.URLRemoteRepository">
<argument value="http://localhost:8020/rmi" />
</bean>

save camel messages between routes

We use Spring DSL to define camel routes. In one case the message headers disappear.
Our design requires an audit trail to help debug issues, and prove that messages are moving as designed.
We use and reference an audit processor to create a message file name from 2 headers, 1 is constant, the other is a unique variable.
We can't use setHeader in the case of the variable one.
Here is a generic example which includes commented attempts that failed:
<route id="msg_in">
<from uri="direct:msg_in" />
<wireTap ref="audit" processorRef="auditPreprocessor" />
<to uri="direct:to_json" />
</route>
<route id="to_json">
<from uri="direct:to_json" />
<!-- the below seemed to have failed -->
<!-- <setProperty propertyName="SaveId"> -->
<!-- <simple>${in.header.UniqueId}</simple> -->
<!-- </setProperty> -->
<bean ref="JDBCProcessor1" />
<!-- headers still exist here -->
<bean ref="ToJSON1" />
<!-- headers still exist here, and wireTap on the next line works -->
<wireTap ref="audit" processorRef="auditPreprocessor" />
<bean ref="toJSON" />
<!-- Message headers do not get to here so we need to set them again ? -->
<setHeader headerName="Hdr1">
<constant>Update1</constant>
</setHeader>
<!-- <setHeader headerName="UniqueId"> -->
<!-- <simple>${exchangeProperty:SaveId}</simple> ... this didn't work -->
<!-- <simple>${properties:SaveId}</simple> ... this didn't work -->
<!-- </setHeader> -->
<to uri="direct:msg_out" />
</route>
<route id="msg_out">
<from uri="direct:msg_out" />
<!-- we try wireTap here but no headers, saved file is null-null
and gets continually overwritten, so no usable audit trail -->
</route>
I spent considerable time trying to find the right way to do this in Spring xml, but no luck yet.
Thanks in advance if anyone can help.

apache camel read headers using spring dsl

I am trying to read request headers using Apache camel 2.14.1 "Rest" component. Below is my spring dsl to configure rest component
<rest path="/a">
<get uri="/{b}">
<route>
<setBody>
<simple>${header.b}:${header.headerName}</simple>
</setBody>
<to uri="activemq:queue:requestQueue?replyTo=responseQueue"/>
</route>
</get>
</rest>
When I call this service(http//localhost:8081/test/a/b) by setting the headers (headerName=1) using postman plugin, then my camel configuration is unable to read header values.
As per the documentation, we can read headers using ${in.header.headerName}, which is returning empty in my case.
Please help me to read header values.
For one thing a path /test/a/b does not match the path you configured with a base of /a and a path pattern of /{b}. You have to drop the /test from your path.
Why you would not get the headers I don't know. A typo maybe in the header names you try to set/access?
The following works for me, using different styles for accessing the in-headers:
<rest path="/header-test">
<get>
<route id="header-test">
<log message="Header: $simple{in.headers[my-header]}" loggingLevel="INFO" logName="header-test" />
<transform>
<simple>${header.my-header}</simple>
</transform>
<log message="Body: $simple{body}" loggingLevel="INFO" logName="header-test" />
</route>
</get>
</rest>

ActiveMQ - delete/purge all queue via command line

Is there a way to delete / purge all queues in ActiveMQ via the command line (win/linux)?
I could only find the commands for a specific queue.
Or maybe there's a way to do this via the activeMQ admin? Again, I only found how to delete/purge the queues one by one, which can be very tedious.
Thanks!
You can do tweak your activemq.xml a bit:
<broker deleteAllMessagesOnStartup="true" ...>
This works with KahaDB message stores (it has problems with JDBC message stores), all your messages get deleted and subsequently queues are cleared.
As you want all queues to be deleted, restarting the broker won't be a costly option to clean everything up.
The purge will happen on 'every' restart
I developed my own ActiveMQ command line utility (activemq-cli) to do this. You can find it here: https://github.com/antonwierenga/activemq-cli (command 'purge-all-queues' or 'remove-all-queues').
As of version 5.0 it looks like this can be done using the CLI provided with ActiveMQ itself:
$ ActiveMQ/bin/activemq purge
1- go to amq bin folder, in my case:
cd /opt/amq/bin
2- run amq client:
./client
3- run purge on desired queue
activemq:purge <QUEUE NAME HERE>
Another possibility is to deploy a small Camel route in a container (e.g. Apache ServiceMix) or simply by executing a java program which contain the route.
For example here is the route I currently use on my development computer where I also have the ServiceMix installed:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"
xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd
http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0 http://aries.apache.org/schemas/blueprint-cm/blueprint-cm-1.1.0.xsd">
<cm:property-placeholder persistent-id="amq.cleanup" update-strategy="reload">
<cm:default-properties>
<cm:property name="amq.local.url" value="tcp://localhost:61616" />
</cm:default-properties>
</cm:property-placeholder>
<camelContext xmlns="http://camel.apache.org/schema/blueprint">
<onException useOriginalMessage="true">
<exception>java.lang.Exception</exception>
<handled>
<constant>true</constant>
</handled>
<to uri="activemq:queue:CLEANUP_DLQ" />
</onException>
<route id="drop-all-queues" autoStartup="true">
<from uri="activemq:queue:*.>" />
<stop/>
</route>
</camelContext>
<bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent">
<property name="brokerURL" value="${amq.local.url}" />
</bean>
</blueprint>

how to use xpath in camel-context.xml to check if a particular node is exist or not

I am trying to develop a content-based routing camel application. This application will look at the folder src/data to see if there is a SOAP request file that has node <e2d:getOrderDetaiRequest>, then that file will be copy into target/message, otherwise the file will be copy to target/other.
Do you know how to use xpath(or any other tools ) to check that condition (i prefer using camel-context.xml file)?
Here is my camel-context
<route>
<from uri="file://c:/src/data?noop=true"/>
<choice>
<when>
<xpath>**???????????????????????????**</xpath>
<to uri="file://c:/target/message"/>
</when>
<otherwise>
<to uri="file://c:/target/other"/>
</otherwise>
</choice>
</route>
And here is the sample of 2 different SOAP requests
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:e2d="http://www.abc.com/Abc11WS">
<soapenv:Header/>
<soapenv:Body>
<e2d:getOrderDetailRequest>
<actionCode>1234</actionCode>
</..>
</...></...>
And
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:lsr="http://www.abc.com/Abc22WS">
<soapenv:Header/>
<soapenv:Body>
<lsr:getProductDetailsRequest>
<productId>12345</...>
</...></...></...>
When using xpath and your xml has namespaces, such as your SOAP message, then you must use namespaces in the xpath expression as well.
There is some details at the Camel docmentation at: http://camel.apache.org/xpath
By using the XML DSL in Camel you can declare the namespace in the XML tag directly such as in the camelContext etc.
<camelContext xmlns="http://camel.apache.org/schema/spring" e2d="http://www.abc.com/Abc11WS">
...
<when>
<xpath>/e2d:getOrderDetailRequest</xpath>
...
But mind that XPaths can be a bit tricky to get working correctly. And that is why we added the logNamespaces in Camel 2.10. See details in the bottom of the this page: http://camel.apache.org/xpath

Resources