save camel messages between routes - spring

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.

Related

ActiveMQ poor performance on large number (tens of milions) of messages

CentOS 7
4 cores, 16G RAM, 500GB SSD
ActiveMQ 5.15.4
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.10+9)
ActiveMQ architecture
Machines 69 and 68 are built with network brokers. The activemq.xml of 68 and 69 are identical except for the relevant names such as broker names, hostname, IP, etc.
Topics in this architecture:
TOPIC_A_ALL_DELIVERED
TOPIC_A_ALL_RECEIVED
TOPIC_A_NN_DELIVERED, NN=00-23
TOPIC_A_NN_RECEIVED, NN=00-23
Persistence days: Current is 2 days, but the expected target is 7 days. This is how long to wait before expiring the message if a consumer doesn't connect back to retrieve it. I use this config: <timeStampingBrokerPlugin ttlCeiling="172800000" zeroExpirationOverride="172800000"/>.
Persistent store: kahadb, limit size is 200GB
Message format is XML, and each message size is about 1K-3K bytes.
Consumers
In addition to durably subscribing to TOPIC_A_ALL_XXXXXX each consumer also durably subscribes to other topics based on its requirements, but I have no idea how fast the consumers can consume the data. Neither do I know whether they actually subscribe all topics the need. I only know sometime some consumers stop receiving data due to debug their code and then connect back.
Producer
The producer is scheduled to run every 30 minutes. Whenever the producer works it only puts data to one single MQ server. The target MQ server depends on the protocol of failover connection.
Every time the producer will put over 800K quantity XML messages to topics starting with TOPIC_A. The XML contains a tag sit_id (00-23) and tag direction (DELIVERED or RECEIVED) so the producer will put each XML to its relevant topic based on the tag site_id and direction in the XML. The producer meanwhile put each XML into TOPIC_A_ALL_XXXXX based on the tag direction in each XML.
Based on the above data the average total quantity of message for each day is about 76,800,000.
Symptom
At beginning no messages are in kahadb. The speed for producer to put queue to a single MQ with one connection is up to 600~700 msgs/sec. As the amount of data increases the speed sending the message slows down. It slows to 3 msgs/sec and sometimes gets stuck. Whenever this situation happens the below situation can be observed:
From htop, one activemq process keeps consuming 100% of CPU (sometime up to 200%)
The free memory is normal (4~8GB at least)
Consumers receive nothing from both MQ servers.
The above situations almost happens everyday.
If I just wait there for 4-6 hours the MQ server will come back. The producer can send at 4xx~5xx msgs/sec, and then consumers can receive data.
This cycle keeps everyday. I really have no idea how to improve this situation. Any suggestions?
activemq.xml
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">
<!-- Allows us to use system properties as variables in this configuration file -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />
<!-- Allows accessing the server log -->
<bean id="logQuery" class="io.fabric8.insight.log.log4j.Log4jLogQuery"
lazy-init="false" scope="singleton"
init-method="start" destroy-method="stop">
</bean>
<!--
The <broker> element is used to configure the ActiveMQ broker.
-->
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="activemq-mdmcs02p-node1" dataDirectory="${activemq.data}" persistent="true" useJmx="true" populateJMSXUserID="true">
<destinations>
<topic physicalName="TOPIC_A.00.Delivered" />
<topic physicalName="TOPIC_A.00.Received" />
<topic physicalName="TOPIC_A.01.Delivered" />
<topic physicalName="TOPIC_A.01.Received" />
<topic physicalName="TOPIC_A.02.Delivered" />
<topic physicalName="TOPIC_A.02.Received" />
<topic physicalName="TOPIC_A.03.Delivered" />
<topic physicalName="TOPIC_A.03.Received" />
<topic physicalName="TOPIC_A.04.Delivered" />
<topic physicalName="TOPIC_A.04.Received" />
<topic physicalName="TOPIC_A.05.Delivered" />
<topic physicalName="TOPIC_A.05.Received" />
<topic physicalName="TOPIC_A.06.Delivered" />
<topic physicalName="TOPIC_A.06.Received" />
<topic physicalName="TOPIC_A.07.Delivered" />
<topic physicalName="TOPIC_A.07.Received" />
<topic physicalName="TOPIC_A.08.Delivered" />
<topic physicalName="TOPIC_A.08.Received" />
<topic physicalName="TOPIC_A.09.Delivered" />
<topic physicalName="TOPIC_A.09.Received" />
<topic physicalName="TOPIC_A.10.Delivered" />
<topic physicalName="TOPIC_A.10.Received" />
<topic physicalName="TOPIC_A.11.Delivered" />
<topic physicalName="TOPIC_A.11.Received" />
<topic physicalName="TOPIC_A.12.Delivered" />
<topic physicalName="TOPIC_A.12.Received" />
<topic physicalName="TOPIC_A.13.Delivered" />
<topic physicalName="TOPIC_A.13.Received" />
<topic physicalName="TOPIC_A.14.Delivered" />
<topic physicalName="TOPIC_A.14.Received" />
<topic physicalName="TOPIC_A.15.Delivered" />
<topic physicalName="TOPIC_A.15.Received" />
<topic physicalName="TOPIC_A.16.Delivered" />
<topic physicalName="TOPIC_A.16.Received" />
<topic physicalName="TOPIC_A.17.Delivered" />
<topic physicalName="TOPIC_A.17.Received" />
<topic physicalName="TOPIC_A.18.Delivered" />
<topic physicalName="TOPIC_A.18.Received" />
<topic physicalName="TOPIC_A.19.Delivered" />
<topic physicalName="TOPIC_A.19.Received" />
<topic physicalName="TOPIC_A.20.Delivered" />
<topic physicalName="TOPIC_A.20.Received" />
<topic physicalName="TOPIC_A.21.Delivered" />
<topic physicalName="TOPIC_A.21.Received" />
<topic physicalName="TOPIC_A.22.Delivered" />
<topic physicalName="TOPIC_A.22.Received" />
<topic physicalName="TOPIC_A.23.Delivered" />
<topic physicalName="TOPIC_A.23.Received" />
<topic physicalName="TOPIC_A_ALL.Delivered" />
<topic physicalName="TOPIC_A_ALL.Received" />
</destinations>
<destinationPolicy>
<policyMap>
<policyEntries>
<policyEntry topic=">" producerFlowControl="false" memoryLimit="4096mb" enableAudit="false" expireMessagesPeriod="60000" >
<!-- The constantPendingMessageLimitStrategy is used to prevent
slow topic consumers to block producers and affect other consumers
by limiting the number of messages that are retained
For more information, see:
http://activemq.apache.org/slow-consumer-handling.html
-->
<deadLetterStrategy>
<sharedDeadLetterStrategy processExpired="false"/>
</deadLetterStrategy>
<pendingMessageLimitStrategy>
<constantPendingMessageLimitStrategy limit="1000"/>
</pendingMessageLimitStrategy>
<networkBridgeFilterFactory>
<conditionalNetworkBridgeFilterFactory replayWhenNoConsumers="true"/>
</networkBridgeFilterFactory>
</policyEntry>
</policyEntries>
</policyMap>
</destinationPolicy>
<!--
<destinationInterceptors>
<virtualDestinationInterceptor>
<virtualDestinations>
<virtualTopic name=">" prefix="TOPIC_A.*" selectorAware="false"/>
</virtualDestinations>
</virtualDestinationInterceptor>
</destinationInterceptors>
-->
<networkConnectors>
<networkConnector uri="static:(tcp://192.168.11.68:61616)" userName="admin" password="XXXXX" dynamicOnly="true" prefetchSize="1" />
</networkConnectors>
<!--
The managementContext is used to configure how ActiveMQ is exposed in
JMX. By default, ActiveMQ uses the MBean server that is started by
the JVM. For more information, see:
http://activemq.apache.org/jmx.html
-->
<managementContext>
<managementContext createConnector="true"/>
</managementContext>
<!--
Configure message persistence for the broker. The default persistence
mechanism is the KahaDB store (identified by the kahaDB tag).
For more information, see:
http://activemq.apache.org/persistence.html
-->
<persistenceAdapter>
<kahaDB directory="/home/activemq/kahadb"
ignoreMissingJournalfiles="true"
checkForCorruptJournalFiles="true"
checksumJournalFiles="true"
enableJournalDiskSyncs="false"
/>
</persistenceAdapter>
<!--
The systemUsage controls the maximum amount of space the broker will
use before disabling caching and/or slowing down producers. For more information, see:
http://activemq.apache.org/producer-flow-control.html
-->
<systemUsage>
<systemUsage>
<memoryUsage>
<memoryUsage percentOfJvmHeap="70" />
</memoryUsage>
<storeUsage>
<storeUsage limit="80 gb"/>
</storeUsage>
<tempUsage>
<tempUsage limit="40 gb"/>
</tempUsage>
</systemUsage>
</systemUsage>
<!--
<sslContext>
<sslContext
keyStore="file:${activemq.base}conf/broker1.ks" keyStorePassword="P#ssw0rd"
/>
</sslContext>
-->
<!--
The transport connectors expose ActiveMQ over a given protocol to
clients and other brokers. For more information, see:
http://activemq.apache.org/configuring-transports.html
-->
<transportConnectors>
<!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->
<transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=1048576000"/>
<transportConnector name="nio" uri="nio://0.0.0.0:61617?trace=true"/>
<!-- <transportConnector name="ssl" uri="ssl://0.0.0.0:61618?trace=true&transport.enabledProtocols=TLSv1.2"/> -->
<transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600&transport.transformer=jms"/>
<!-- <transportConnector name="amqp+ssl" uri="amqp://0.0.0.0:5673?maximumConnections=1000&wireFormat.maxFrameSize=104857600&transport.enabledProtocols=TLSv1.2"/> -->
<!-- <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> -->
<!-- <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> -->
<!-- <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> -->
</transportConnectors>
<!-- destroy the spring context on shutdown to stop jetty -->
<shutdownHooks>
<bean xmlns="http://www.springframework.org/schema/beans" class="org.apache.activemq.hooks.SpringContextHook" />
</shutdownHooks>
<plugins>
<!-- 86,400,000 ms = 1 day -->
<timeStampingBrokerPlugin ttlCeiling="172800000" zeroExpirationOverride="172800000"/>
<jaasAuthenticationPlugin configuration="activemq" />
<authorizationPlugin>
<map>
<authorizationMap>
<authorizationEntries>
<authorizationEntry queue=">" read="admins" write="admins" admin="admins" />
<authorizationEntry topic=">" read="admins" write="admins" admin="admins" />
<authorizationEntry topic="TOPIC_A.>" read="mdmsusers" write="mdmsusers" />
<authorizationEntry topic="TOPIC_A.Delivered" read="pwsusers" />
<authorizationEntry topic="ActiveMQ.Advisory.>" read="mdmsusers,pwsusers" write="mdmsusers,pwsusers" admin="mdmsusers,pwsusers"/>
</authorizationEntries>
<tempDestinationAuthorizationEntry>
<tempDestinationAuthorizationEntry read="admins" write="admins" admin="admins"/>
</tempDestinationAuthorizationEntry>
</authorizationMap>
</map>
</authorizationPlugin>
</plugins>
</broker>
<!--
Enable web consoles, REST and Ajax APIs and demos
The web consoles requires by default login, you can disable this in the jetty.xml file
Take a look at ${ACTIVEMQ_HOME}/conf/jetty.xml for more details
-->
<import resource="jetty.xml"/>
</beans>
I suspect you are hitting some sort of combination of flow control, fast producer, slow consumer, pending message limit or invalid client registration issue that needs to be sorted out. Perhaps even bug or optimization in that version of ActiveMQ.
Suggested steps:
Upgrade to latest 5.15.x. There are a lot of fixes and it does not make sense to troubleshoot against a build that old.
Enable Advisory Messages for advisoryForFastProducer and advisoryForSlowConsumer on the destinations. This will give you an ActiveMQ.Advisory topic to show when those scenarios occur.
Investigate the client and connections to make sure they are all properly registered with clientId and suscriptionName to get a durable subscription. Remember: 2 connections cannot share clientId+subscriptioName
Consider moving to Virtual Topics. This is where messages are sent to the topic and consumers read from queues. Much more flexibility and visibility over what is going on with flows. Also-- bonus it makes multi-broker shared subscriptions straight forward.

SAP Hybris adding Doctype to cXML Punchout

Currently our cXML Punchout implementation (SAP hybris standard) does not print the Doctype on a response.
The the endsyste needs it:
Wed Sep 02 00:19:42 PDT 2020 (T12:prealm_1234:global\c1234:PasswordAdapter1:db2wer:C123_UI1)
(application.cxml:ERROR) [ID1234]: CXMLDOMRequester: Unable to parse cXML response with error:
org.xml.sax.SAXParseException: Document root element "cXML", must match DOCTYPE root "null".
I tried to do some research:
One request goes to de.hybris.platform.b2bpunchoutaddon.controllers.pages.DefaultPunchOutSetUpController.handlePunchOutSetUpRequest() and it returns a CXML Object. This Object goes through some mapper and converter, but it adds no where the Doctype.
Then I found de.hybris.platform.b2bpunchoutaddon.converter.CXMLJaxb2MessageConverter. This MessageConverter adds the Doctype to the xml header. But it never runs.
For me the spring configuration looks correct:
<alias name="cXMLJaxb2MessageConverter" alias="jaxbMessageConverter" />
<bean id="cXMLJaxb2MessageConverter" class="de.hybris.platform.b2bpunchoutaddon.converter.CXMLJaxb2MessageConverter"/>
Right now I despair on this problem. Does any of you know how to fix it?
This is because in your storefront extension you have the following setting of message converters:
<!-- activates annotation driven binding -->
<mvc:annotation-driven ignore-default-model-on-redirect="true" validator="validator">
<mvc:message-converters>
<bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/>
<bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"/>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
</mvc:message-converters>
</mvc:annotation-driven>
so, this spring config will of course ignore the bean which your b2bpunchoutaddon creates
<alias name="cXMLJaxb2MessageConverter" alias="jaxbMessageConverter" />
<bean id="cXMLJaxb2MessageConverter" class="de.hybris.platform.b2bpunchoutaddon.converter.CXMLJaxb2MessageConverter"/>
My fix for this was to use change my storefront spring mvc config to use bean with the id="jaxbMessageConverter" instead of an inline bean:
<bean id="jaxbMessageConverter" class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"/>
<!-- activates annotation driven binding -->
<mvc:annotation-driven ignore-default-model-on-redirect="true" validator="validator">
<mvc:message-converters>
<bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/>
<ref bean="jaxbMessageConverter"/>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
</mvc:message-converters>
</mvc:annotation-driven>
Now, we know that the alias will work and the response will contain the doctype:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE cXML SYSTEM "http://xml.cXML.org/schemas/cXML/1.2.024/cXML.dtd">
<cXML payloadID="1609762719111.6059#DESKTOP-3HR841G" timestamp="2021-01-04T14:18:39+02:00" xml:lang="en-US">
<Response>
<Status code="200" text="success"/>
<PunchOutSetupResponse>
<StartPage>
<URL>foo.bar.bla</URL>
</StartPage>
</PunchOutSetupResponse>
</Response>
</cXML>

How load multiple camel context in 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>

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>

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>

Resources