Do Camel Splitters preserve exchange body after they execute? - java

Java 8 and Apache Camel 2.19.5 here. I have the following bean processors:
#Component("foobarResolver")
public class FoobarResolver {
public List<Foobar> resolve(Fizzbuzz fizzbuzz) {
List<Foobar> foobars = new ArrayList<Foobar>();
// Use some logic in here to make the fizzbuzz populate the foobars list.
return foobars;
}
}
#Component("fizzbuzzProcessor")
public class FizzbuzzProcessor {
public FizzbuzzOutput process(Fizzbuzz fizzbuzz) {
// Blah whatever
}
}
And the following Camel route:
<route id="fizzbuzzHandler">
<!-- XML '<fizzbuzz>' messages get sent here by an upstream process -->
<from uri="activemq:fizzbuzzes"/>
<!-- Use XStream to deserialize the XML into a 'Fizzbuzz' POJO instance -->
<unmarshal ref="xs"/>
<split>
<method ref="bean:foobarResolver"/>
<to uri="activemq:analyze"/>
</split>
<!-- Now assuming our body is once again the Fizzbuzz we can just continue as normal... -->
<!-- Process the fizzbuzz -->
<to uri="bean:fizzbuzzProcessor"/>
<!-- Send fizzbuzzProcessor's output to 'output' queue -->
<to uri="activemq:output"/>
</route>
So as you can see, the deserialized Fizzbuzz instance gets sent to the FoobarResolver bean processor, which turns that instance into a List<Foobar> and then sends each Foobar off to the analyze queue, one by one. At least thats the intention of my design anyways!
What I'm curious is: after the split, what does the exchange body become? Does it "revert" back to the Fizzbuzz (which is what I want), or is the exchange body now the List<Foobar> produced by the FoobarResolver (which is NOT what I want)? If the body is now the List<Foobar>, how could I reconfigure things so that the FizzbuzzProcessor receives a Fizzbuzz instead?

It appears to revert to the pre-split body:
#SpringBootApplication
public class SocamelApplication extends RouteBuilder implements ApplicationRunner {
#Autowired
private FooProcessor fooProcessor;
public static void main(String[] args) {
SpringApplication.run(SocamelApplication.class, args);
}
#Override
public void run(ApplicationArguments args) throws Exception {
Thread.sleep(5000);
}
#Override
public void configure() throws Exception {
from("timer://foo?period=100&repeatCount=1").setBody()
.constant(Arrays.asList("Hello", "World"))
.log("1 >>> ${body} ")
.split(body())
.log("2 >>> ${body}")
.bean(fooProcessor)
.log("3 >>> ${body}")
.end()
.log("4 >>> ${body}");
}
#Bean
public FooProcessor fooProcessor() {
return new FooProcessor();
}
}
class FooProcessor implements Processor {
#Override
public void process(Exchange exchange) throws Exception {
String reverseMe = exchange.getIn()
.getBody(String.class);
String reversed = new StringBuilder(reverseMe).reverse()
.toString();
exchange.getOut()
.setBody(reversed);
}
}
Yields:
1 >>> Hello,World
2 >>> Hello
3 >>> olleH
2 >>> World
3 >>> dlroW
4 >>> Hello,World

Related

Mule 4 is modifying Java object variables

I'm migrating my Mule apps from 3.9.0 to Mule 4.4.0. I'm using a Java object to propagate metadata and other objects across transports. Here is a snippet of that class:
package com.test;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
public class DataWrapper implements Serializable {
private static final long serialVersionUID = 1L;
private final Map<String, Object> properties = new HashMap<>();
private Object payload;
private final Object originalPayload;
public DataWrapper(final Object payload) {
this(payload, false);
}
public DataWrapper(final Object payload, boolean playback) {
this.originalPayload = payload;
this.payload = payload;
}
#SuppressWarnings("unchecked")
public <T> T getProperty(String name, T defaultValue) {
if(properties.containsKey(name)) {
return (T) properties.get(name);
} else {
return defaultValue;
}
}
public Object getProperty(String name) {
return getProperty(name, null);
}
public void setProperty(String name, Object value) {
properties.put(name, value);
}
public void setProperties(Map<String, Object> additional) {
properties.putAll(additional);
}
public Object getPayload() {
return payload;
}
public void setPayload(Object payload) {
this.payload = payload;
}
public Object getOriginalPayload() {
return originalPayload;
}
public static DataWrapper wrapData(Object payload) {
return new DataWrapper(payload);
}
public static DataWrapper wrapData(Object payload, Map<String, Object> properties) {
DataWrapper wrapper = new DataWrapper(payload);
wrapper.setProperties(properties);
return wrapper;
}
}
the static methods being called (simplified for example):
public class MyTransformers {
public static DataWrapper addProperties(DataWrapper wrapper, Map<String, Object> properties) {
//process payload and add properties/objects
wrapper.setProperties(properties);
return wrapper;
}
public static String doSomethingWithPayload(DataWrapper wrapper, Map<String, Object> properties) {
//process payload and add properties/objects
return (String) wrapper.getPayload();
}
public static String doSomethingElse(DataWrapper wrapper) {
//do something else with payload
return (String) wrapper.getPayload();
}
}
and the flows:
<?xml version="1.0" encoding="UTF-8"?>
<mule
xmlns:sockets="http://www.mulesoft.org/schema/mule/sockets"
xmlns:vm="http://www.mulesoft.org/schema/mule/vm"
xmlns:java="http://www.mulesoft.org/schema/mule/java"
xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/current/mule-vm.xsd
http://www.mulesoft.org/schema/mule/java http://www.mulesoft.org/schema/mule/java/current/mule-java.xsd
http://www.mulesoft.org/schema/mule/sockets http://www.mulesoft.org/schema/mule/sockets/current/mule-sockets.xsd">
<vm:config name="DefaultVmConnector" doc:name="VM Config" doc:id="786119a5-8fd8-40b8-a145-bfbf5df6a505" >
<vm:queues >
<vm:queue queueName="ReportsEndpoint" />
<vm:queue queueName="PublishEndpoint" />
</vm:queues>
</vm:config>
<sockets:listener-config name="UDP_Config" doc:name="Sockets Listener config" doc:id="b2ec3926-6a0b-4612-97e8-fe9f4011fbad" >
<sockets:udp-listener-connection host="192.168.1.203" port="12121" />
</sockets:listener-config>
<flow name="TestPublishFlow" doc:id="05a95422-080b-491e-9a4d-efc82f10b399" >
<sockets:listener doc:name="Listener" doc:id="5be9224a-be1b-4779-a137-121376cd890d" config-ref="UDP_Config" outputMimeType="text/json"/>
<java:invoke-static doc:name="Data Wrapper" doc:id="9fa629cc-0520-4c00-beae-15f849568d3b" class="com.test.DataWrapper" method="wrapData(java.lang.Object)" outputMimeType="application/java">
<java:args ><![CDATA[#[{payload : payload}]]]></java:args>
</java:invoke-static>
<vm:publish doc:name="Publish to VM" doc:id="b6497fb1-3a57-468c-bcb6-089372407787" config-ref="DefaultVmConnector" sendCorrelationId="NEVER" queueName="PublishEndpoint"/>
</flow>
<flow name="publisher-flow" doc:id="4c765b98-68df-4af2-a517-73bddfe8cc25" >
<vm:listener doc:name="Publish Endpoint" doc:id="a8589268-f5ea-4ebe-a11f-760ff32c2e1f" config-ref="DefaultVmConnector" numberOfConsumers="2" queueName="PublishEndpoint"/>
<java:invoke-static doc:name="Some Business Logic" doc:id="ee53fe99-f459-4581-892e-00e09a8a10e2" class="com.test.MyTransformers" outputMimeType="application/java" method="addProperties(com.test.DataWrapper,java.util.Map)">
<java:args ><![CDATA[#[{ wrapper:payload, properties:{ ClientId:p('source.clientId'), Source:p('data.source'), Metadata:p('data.metadata'), MimeType:p('data.mimetype')}}]]]></java:args>
</java:invoke-static>
<choice doc:name="Choice" doc:id="7976bc82-67d4-4534-b47b-80ed7e287f07" >
<when expression="#[Java::isInstanceOf(payload.payload, 'com.test.DataWrapper')]">
<java:invoke-static doc:name="Do Something" doc:id="528cdafa-9be1-4433-aaf5-0e0352078757" outputMimeType="application/java" class="com.test.MyTransformers" method="doSomethingWithPayload(com.test.DataWrapper,java.util.Map)">
<java:args ><![CDATA[#[{ wrapper : payload, prettyprint : p('xml.prettyprint'), validate : p('xml.validate') }]]]></java:args>
</java:invoke-static>
</when>
<otherwise >
<java:invoke-static doc:name="Do Something Else" doc:id="6d63d9e7-12be-4d43-9990-02b897ec0cee" class="com.test.MyTransformers" method="doSomethingElse(com.test.DataWrapper)" outputMimeType="application/java">
<java:args ><![CDATA[#[{ wrapper : payload }]]]></java:args>
</java:invoke-static>
</otherwise>
</choice>
<logger level="INFO" doc:name="Placeholder" doc:id="800d22cd-55a5-4ee9-a280-497d2f276a63" message="#[payload]"/>
</flow>
</mule>
I need to keep the original message and the processed message to store for later use.
When payload and originalPayload are set to a String object in DataWrapper and the mule message goes through a VM transport, those objects become org.mule.runtime.core.internal.streaming.bytes.ManagedCursorStreamProvider.
Before sending to VM publisher the fields payload and originalpayload in DataWrapper are:
{ "count" : 0, "comment" : "This is a test"}
and after it is:
org.mule.runtime.core.internal.streaming.bytes.ManagedCursorStreamProvider#162b291f
I'm also getting a serialization exception when going through the VM endpoint:
Caused by: java.io.NotSerializableException: org.mule.runtime.core.internal.streaming.bytes.ManagedCursorStreamProvider
How can I prevent that from happening without changing the type of payload and originalPayload from Object to String?
Mule 4 implements streaming in most components, unlike Mule 3 which implemented it only for some. The payload returned by the HTTP Listener is a stream implemented by the ManagedCursorStreamProvider. It was not added by the VM connector, it was the original payload. Most components in Mule 4 now how to use the stream implementation transparently, so usually a user doesn't need to care if their JSON payload is in a stream or in a Java string. The exception is when you do actual Java code you need to know the actual classes.
It is not a good practice and discouraged to add Mule specific APIs and classes to your custom Java code to make them 'stream aware'. Instead an easier solution is to let DataWeave do its transformation magic and convert to a Java object automatically, in this case a String.
Example:
<sockets:listener doc:name="Listener" config-ref="UDP_Config" outputMimeType="text/json"/>
<ee:transform doc:name="Transform Message">
<ee:message >
<ee:set-payload ><![CDATA[%dw 2.0
output application/java
---
write(payload,"application/java")
]]>
</ee:set-payload>
</ee:message>
</ee:transform>
<java:invoke-static doc:name="Data Wrapper" class="com.test.DataWrapper" method="wrapData(java.lang.Object)" outputMimeType="application/java">
<java:args ><![CDATA[#[{payload : payload}]]]></java:args>
</java:invoke-static>
The write() function writes a string from the payload that you can use in your wrapper class. This works for this particular scenario. You will need to change classes if you do some other permutations of inputs and Java code.

How do I produce just one message using Spring Cloud Stream w/o deprecated #Output, or turn off polling?

I am trying to publish just one message to Kafka, using Spring Cloud without any deprecated classes/methods or annotations. I would also like to be able to easily change the payload.
So for all clarity, I am trying to not use the deprecated #Output annotation, nor any KafkaTemplate.
My configuration:
spring:
cloud:
stream:
bindings:
message-out-0:
destination: ${spring.application.name}
producer:
key:
serializer:
type: string
format: utf-8
charset: utf-8
value:
serializer:
type: string
format: utf-8
charset: utf-8
My code - what I have tried so far:
#Component
#RequiredArgsConstructor
public class ApplicationAnnouncer implements CommandLineRunner {
private final MessageService messageService;
#Override
public void run(String... args) throws Exception {
messageService.value = "Application started...";
messageService.message();
}
}
One attempt:
#Configuration
public class MessageService {
public Object value;
#Bean
public Supplier<Message<?>> message () {
return () -> MessageBuilder.withPayload(value).build();
}
}
Another attempt:
#Configuration
public class MessageService {
public Object value;
#Bean
public Supplier<Flux<?>> message () {
return () -> Flux.fromStream(Stream.generate(() -> {
try {
Thread.sleep(1000);
return value;
} catch (Exception e) {
// ignore
}
return null;
})).subscribeOn(Schedulers.elastic()).share();
}
}
Output in console consumer for both attempts:
Hello World!
Hello World!
Hello World!
Hello World! // ... Repeated every second
The documentation states:
The framework provides a default polling mechanism (answering the question of "Who?") that will trigger the invocation of the supplier and by default it will do so every second (answering the question of "How often?").
But what if I don't want it to poll every second?
It is weird how I'm supplying the MessageService with the message...
Is it configuration? Or is it a service?
I have yet to find the most basic example of just pushing ONE CUSTOMIZABLE MESSAGE to Kafka.
You can tap into the cloud-stream-bindings by using a StreamBridge:
#Component
#RequiredArgsConstructor
public class ApplicationAnnouncer implements CommandLineRunner {
private final StreamBridge streamBridge;
#Override
public void run(String... args) throws Exception {
streamBridge.send("message-out-0", "Application started...");
}
}
The first string is the binding-name provided in the application settings derived from the bean providing the function.
You don't even need an actual bean from which the binding-name is derived. in that case, any name will do.
You can find some samples here.

how do I Mock endpoints with blueprint in camel?

I'm writing an application using camel for deployment (eventually) in a fuse container. The nature of the project requires that I mix and match Java and XML DSL.
I'm having trouble getting the mock framework to work properly with blueprint.
Here's my unit test, based completely on the example here.
public class MockNotWorking extends CamelBlueprintTestSupport {
#Test
public void testAdvisedMockEndpointsWithPattern() throws Exception {
context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() {
#Override
public void configure() throws Exception {
mockEndpoints("log*");
}
});
getMockEndpoint("mock:log:foo").expectedBodiesReceived("Bye World");
getMockEndpoint("mock:result").expectedBodiesReceived("Bye World");
template.sendBody("direct:start", "Hello World");
// additional test to ensure correct endpoints in registry
assertNotNull(context.hasEndpoint("direct:start"));
assertNotNull(context.hasEndpoint("log:foo"));
assertNotNull(context.hasEndpoint("mock:result"));
// only the log:foo endpoint was mocked
assertNotNull(context.hasEndpoint("mock:log:foo"));
assertNull(context.hasEndpoint("mock:direct:start"));
assertNull(context.hasEndpoint("mock:direct:foo"));
assertMockEndpointsSatisfied();
}
#Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
#Override
public void configure() throws Exception {
from("direct:start").to("direct:foo").to("log:foo").to("mock:result");
from("direct:foo").transform(constant("Bye World"));
}
};
}
protected String getBlueprintDescriptor() {
return "OSGI-INF/blueprint/blueprint.xml";
}
}
I have copied verbatim the example here, and modified it very slightly so we extend CamelBlueprintTestSupport instead of CamelTestSupport. This requires over-riding getBlueprintDescriptor to point to my blueprint xml, in which I have defined one very basic (and completely irrelevant to the test) route:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<camelContext id="validationRoute" xmlns="http://camel.apache.org/schema/blueprint" >
<route id="validation">
<from uri="direct:validation" />
<log message="validating..." />
</route>
</camelContext>
</blueprint>
The test fails with:
java.lang.AssertionError: mock://log:foo Received message count. Expected: <1> but was: <0>
So this means the message did not reach the mock endpoint. Change CamelBlueprintTestSupport for CamelTestSupport and it works.
So how do I get mocks like this working correctly with blueprint?
When you use blueprint, it imports all the routes you have defined in the blueprint xml file(s), and adds them to the CamelContext.
The reason this breaks things is that the context.getRouteDefinitions().get(0) no longer refers to the only route - there are now more than one. So when you add the AdviceWithRouteBuilder, it could be added to the wrong route.
The following code fixes the problem (and will work for non-blueprint tests too):
List<RouteDefinition> routes = context.getRouteDefinitions();
for (int i=0; i<routes.size(); i++) {
context.getRouteDefinitions().get(i).adviceWith(context, new AdviceWithRouteBuilder() {
#Override
public void configure() throws Exception {
// mock all endpoints
mockEndpoints("log*");
}
});
}
======update======
A better way of doing this is rather than mocking all routes, find our specific route by id and then apply the advice. This means first setting the route id:
from("direct:start").routeId("start").to("direct:foo").to("log:foo").to("mock:result");
And then looking up the route by id and calling adviceWith as before:
context.getRouteDefinition("start").adviceWith(context, new AdviceWithRouteBuilder() {
#Override
public void configure() throws Exception {
// mock log endpoints
mockEndpoints("log*");
}
});
Actually it depends on what version of Camel you are using, some methods doesn't work as expected. Its improved a lot better after 2.12 if I remember right. (2.15 is way better)
After all my encounters with Camel unit testing, I ended up documenting all stuffs here:
http://bushorn.com/unit-testing-apache-camel/
http://bushorn.com/camel-unit-testing-using-mock-endpoint/
By the way, instead of this "mockEndpoints("log*");", I would do this:
weaveByToString(".direct:foo.").after().to("mock:log"); (This sounds weird, I know ;) )
or if you can set an endpoint id
weaveById("endpoint-id-of-direct-foo").after().to("mock:log");
or
weaveAddLast().to("mock:log");

Apache camel intercept, update the Exchange message for all RouteBuilders, and continue

I have a CamelConfiguration that configures 15 Routes.
public class CamelRoutesConf extends CamelConfiguration {
#Override
public List<RouteBuilder> configure() {
List<RouteBuilder> routes = super.routes();
routes.forEach(router -> {
router.onException(Exception.class).delay(5000);
});
return routes;
}
}
What I want to achieve is check the header of every incoming Message (exchange.getHeaders()) inside the route, and add a header if it doesn't exist.
I can achieve that using Processor inside each RouteBuilder. Ex.
public class ArtistHiredRouteBuilder extends RouteBuilder {
#Override
public void configure(){
from(incomingArtistsQ)
.process(new Processor(){
public void process(Exchange exchange){
exchange.getIn().setHeader("JMSCorrelationId", randomNumberOfLength10());
}
})
.to(outgoingArtistsQ)
}
Purpose is to use same id between all exchange messages, so that it becomes easier to relate them later.
So, is there a Camel way of doing this in CamelConfiguration#configure so that it applies to all the Routes.
I expected intercepting as below.
public class CamelRoutesConf extends CamelConfiguration {
#Override
public List<RouteBuilder> configure() {
List<RouteBuilder> routes = super.routes();
routes.forEach(router -> {
router.interceptFrom().process(headerProcessor)
router.onException(Exception.class).delay(5000);
});
}
}
It will be intecepted but doesn't seem to continue with .to() in each RouteBuilder.
References
http://camel.apache.org/intercept.html
http://www.davsclaus.com/2009/05/on-road-to-camel-20-interceptors-round.html
you can use the interceptFrom() clause to set your header value for all routes
// intercept all incoming routes and do something...
interceptFrom().setHeader(JMSCorrelationId", randomNumberOfLength10());

How to route Rest request from a local service to a remote one using Camel

I am trying to route a rest request from a cxf rest service to another. I have had a look at http://camel.apache.org/cxfrs.html which helped understand part of the process. I have a classCastException at the level of the remoteService Invocation.
What am I doing wrong ?
<cxf:rsServer id="exposedService" address="/exposed/"
serviceClass="com.example.project.ExposedService" />
<!-- using different classes since we are not just proxying -->
<cxf:rsClient id="remoteService" address="http://remote.com/service"
serviceClass="com.example.project.RemoteService" />
<camel:camelContext xmlns="http://camel.apache.org/schema/spring">
<package>com.example.project</package>
</camel:camelContext>
Service Classes:
#Path("/myservice")
public class ExposedService {
#POST
#Consumes("application/xml")
public void postResource(javax.xml.transform.Source resource) {
// source : not using jaxb just plain xml
// only serves to configure the endpoint (?)
}
}
public class RemoteService {
#POST
#Consumes("application/xml")
public void postResource(javax.xml.transform.Source resource) {
// source : not using jaxb just plain xml
// only serves to configure the endpoint (?)
}
}
RouteBuilder:
public class MyRouteBuilder extends RouteBuilder {
public void configure() {
from("cxfrs://bean://exposedService")
.process(...) // a few System.out.println's
.to("cxfrs://bean://remoteService")
;
}
}
Stacktrace:
| ERROR | qtp-2045010446-1 | DefaultErrorHandler | 68 - org.apache.camel.camel-core - 2.6.0 | Failed delivery for exchangeId: ID-Lab-local-52879-1305561896560-7-2. Exhausted after delivery attempt: 1 caught: java.lang.ClassCastException
java.lang.ClassCastException
at java.lang.Class.cast(Class.java:2990)[:1.6.0_24]
at org.apache.cxf.jaxrs.client.WebClient.invoke(WebClient.java:329)[116:org.apache.cxf.bundle:2.3.2]
at org.apache.camel.component.cxf.jaxrs.CxfRsProducer.invokeHttpClient(CxfRsProducer.java:147)[118:org.apache.camel.camel-cxf:2.6.0]
at org.apache.camel.component.cxf.jaxrs.CxfRsProducer.process(CxfRsProducer.java:77)[118:org.apache.camel.camel-cxf:2.6.0]
at org.apache.camel.impl.converter.AsyncProcessorTypeConverter$ProcessorToAsyncProcessorBridge.process(AsyncProcessorTypeConverter.java:50)[68:org.apache.camel.camel-core:2.6.0]
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:70)[68:org.apache.camel.camel-core:2.6.0]
at org.apache.camel.processor.SendProcessor$2.doInAsyncProducer(SendProcessor.java:104)[68:org.apache.camel.camel-core:2.6.0]
at org.apache.camel.impl.ProducerCache.doInAsyncProducer(ProducerCache.java:272)[68:org.apache.camel.camel-core:2.6.0]
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:98)[68:org.apache.camel.camel-core:2.6.0]
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:70)[68:org.apache.camel.camel-core:2.6.0]
at org.apache.camel.processor.DelegateAsyncProcessor.processNext(DelegateAsyncProcessor.java:98)[68:org.apache.camel.camel-core:2.6.0]
at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:89)[68:org.apache.camel.camel-core:2.6.0]
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:68)[68:org.apache.camel.camel-core:2.6.0]
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:70)[68:org.apache.camel.camel-core:2.6.0]
at org.apache.camel.processor.DelegateAsyncProcessor.processNext(DelegateAsyncProcessor.java:98)[68:org.apache.camel.camel-core:2.6.0]
at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:89)[68:org.apache.camel.camel-core:2.6.0]
at org.apache.camel.processor.interceptor.TraceInterceptor.process(TraceInterceptor.java:174)[68:org.apache.camel.camel-core:2.6.0]
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:70)[68:org.apache.camel.camel-core:2.6.0]
at org.apache.camel.processor.RedeliveryErrorHandler.processErrorHandler(RedeliveryErrorHandler.java:299)[68:org.apache.camel.camel-core:2.6.0]
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:208)[68:org.apache.camel.camel-core:2.6.0]
at org.apache.camel.processor.DefaultChannel.process(DefaultChannel.java:269)[68:org.apache.camel.camel-core:2.6.0]
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:70)[68:org.apache.camel.camel-core:2.6.0]
at org.apache.camel.processor.Pipeline.process(Pipeline.java:125)[68:org.apache.camel.camel-core:2.6.0]
at org.apache.camel.processor.Pipeline.process(Pipeline.java:80)[68:org.apache.camel.camel-core:2.6.0]
at org.apache.camel.processor.UnitOfWorkProcessor.process(UnitOfWorkProcessor.java:102)[68:org.apache.camel.camel-core:2.6.0]
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:70)[68:org.apache.camel.camel-core:2.6.0]
at org.apache.camel.processor.DelegateAsyncProcessor.processNext(DelegateAsyncProcessor.java:98)[68:org.apache.camel.camel-core:2.6.0]
at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:89)[68:org.apache.camel.camel-core:2.6.0]
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:68)[68:org.apache.camel.camel-core:2.6.0]
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:91)[68:org.apache.camel.camel-core:2.6.0]
at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:85)[68:org.apache.camel.camel-core:2.6.0]
at org.apache.camel.component.cxf.jaxrs.CxfRsInvoker.syncInvoke(CxfRsInvoker.java:134)[118:org.apache.camel.camel-cxf:2.6.0]
at org.apache.camel.component.cxf.jaxrs.CxfRsInvoker.performInvocation(CxfRsInvoker.java:68)[118:org.apache.camel.camel-cxf:2.6.0]
at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:89)[116:org.apache.cxf.bundle:2.3.2]
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:153)[116:org.apache.cxf.bundle:2.3.2]
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:87)[116:org.apache.cxf.bundle:2.3.2]
at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:58)[116:org.apache.cxf.bundle:2.3.2]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)[:1.6.0_24]
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)[:1.6.0_24]
at java.util.concurrent.FutureTask.run(FutureTask.java:138)[:1.6.0_24]
at org.apache.cxf.workqueue.SynchronousExecutor.execute(SynchronousExecutor.java:37)[116:org.apache.cxf.bundle:2.3.2]
at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:106)[116:org.apache.cxf.bundle:2.3.2]
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:255)[116:org.apache.cxf.bundle:2.3.2]
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:113)[116:org.apache.cxf.bundle:2.3.2]
at org.apache.cxf.transport.http_osgi.OsgiDestination.doMessage(OsgiDestination.java:79)[116:org.apache.cxf.bundle:2.3.2]
at org.apache.cxf.transport.http_osgi.OsgiServletController.invokeDestination(OsgiServletController.java:336)[116:org.apache.cxf.bundle:2.3.2]
at org.apache.cxf.transport.http_osgi.OsgiServletController.invoke(OsgiServletController.java:108)[116:org.apache.cxf.bundle:2.3.2]
at org.apache.cxf.transport.http_osgi.OsgiServlet.invoke(OsgiServlet.java:53)[116:org.apache.cxf.bundle:2.3.2]
at org.apache.cxf.transport.http_osgi.SpringOsgiServlet.invoke(SpringOsgiServlet.java:48)[116:org.apache.cxf.bundle:2.3.2]
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:179)[116:org.apache.cxf.bundle:2.3.2]
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:103)[116:org.apache.cxf.bundle:2.3.2]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:595)[93:org.apache.geronimo.specs.geronimo-servlet_3.0_spec:1.0]
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:159)[116:org.apache.cxf.bundle:2.3.2]
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)[94:org.apache.servicemix.bundles.jetty:6.1.25.1]
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:390)[94:org.apache.servicemix.bundles.jetty:6.1.25.1]
at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.handle(HttpServiceServletHandler.java:64)[133:org.ops4j.pax.web.pax-web-jetty:0.7.4]
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)[94:org.apache.servicemix.bundles.jetty:6.1.25.1]
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)[94:org.apache.servicemix.bundles.jetty:6.1.25.1]
at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.handle(HttpServiceContext.java:111)[133:org.ops4j.pax.web.pax-web-jetty:0.7.4]
at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:68)[133:org.ops4j.pax.web.pax-web-jetty:0.7.4]
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)[94:org.apache.servicemix.bundles.jetty:6.1.25.1]
at org.mortbay.jetty.Server.handle(Server.java:326)[94:org.apache.servicemix.bundles.jetty:6.1.25.1]
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)[94:org.apache.servicemix.bundles.jetty:6.1.25.1]
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:943)[94:org.apache.servicemix.bundles.jetty:6.1.25.1]
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756)[94:org.apache.servicemix.bundles.jetty:6.1.25.1]
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)[94:org.apache.servicemix.bundles.jetty:6.1.25.1]
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)[94:org.apache.servicemix.bundles.jetty:6.1.25.1]
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:410)[94:org.apache.servicemix.bundles.jetty:6.1.25.1]
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)[94:org.apache.servicemix.bundles.jetty:6.1.25.1]
there is a working example of doing nearly the same thing here...
http://camel.apache.org/cxf-proxy-example.html
start with this, then drop your changes in one-by-one and see where it breaks...

Categories