I'm using the following route:
<route>
<from uri="file:...
<setHeader headerName="CamelHttpMethod">
<constant>PUT</constant>
</setHeader>
<to uri="jetty:http://localhost:55556/extract?restletMethod=PUT"/>
<to uri="ejb:java:global/Abc/Bean?method=doSomething(${body}, ${headers})"/>
</route>
Endpoint:
public InputStream extract(#Body InputStream inputStream, #Headers Map<String, Object> headers) throws Exception {
byte[] b = IOUtils.toByteArray(inputStream);
// do some stuff
headers.put("extraction", ...);
return new ByteArrayInputStream(b);
}
If the file size exceeds 2 MB the following exception occurs:
(Camel-Jetty http proxy + large response data casue issue: Buffering capacity exceeded)
JettyClient failed cause by: Buffering capacity exceeded. Exchange[ID-debianjk-scsynergy-local-43219-1479191420664-41-8]. Caused by: [java.lang.IllegalArgumentException - Buffering capacity exceeded]
at org.apache.camel.component.jetty9.JettyContentExchange9.doTaskCompleted(JettyContentExchange9.java:156)
at org.apache.camel.component.jetty9.JettyContentExchange9$2.onComplete(JettyContentExchange9.java:222)
at org.eclipse.jetty.client.ResponseNotifier.notifyComplete(ResponseNotifier.java:193)
at org.eclipse.jetty.client.ResponseNotifier.notifyComplete(ResponseNotifier.java:185)
at org.eclipse.jetty.client.HttpReceiver.terminateResponse(HttpReceiver.java:453)
at org.eclipse.jetty.client.HttpReceiver.terminateResponse(HttpReceiver.java:434)
at org.eclipse.jetty.client.HttpReceiver.responseContent(HttpReceiver.java:360)
at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.content(HttpReceiverOverHTTP.java:254)
at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.content(HttpReceiverOverHTTP.java:38)
at org.eclipse.jetty.http.HttpParser.parseContent(HttpParser.java:1472)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:1245)
at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.parse(HttpReceiverOverHTTP.java:156)
at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.process(HttpReceiverOverHTTP.java:117)
at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.receive(HttpReceiverOverHTTP.java:69)
at org.eclipse.jetty.client.http.HttpChannelOverHTTP.receive(HttpChannelOverHTTP.java:89)
at org.eclipse.jetty.client.http.HttpConnectionOverHTTP.onFillable(HttpConnectionOverHTTP.java:123)
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalArgumentException: Buffering capacity exceeded
at org.eclipse.jetty.client.util.BufferingResponseListener.onContent(BufferingResponseListener.java:114)
at org.eclipse.jetty.client.api.Response$Listener$Adapter.onContent(Response.java:245)
at org.eclipse.jetty.client.ResponseNotifier.notifyContent(ResponseNotifier.java:124)
at org.eclipse.jetty.client.ResponseNotifier.access$100(ResponseNotifier.java:35)
at org.eclipse.jetty.client.ResponseNotifier$ContentCallback.process(ResponseNotifier.java:274)
at org.eclipse.jetty.util.IteratingCallback.processing(IteratingCallback.java:246)
at org.eclipse.jetty.util.IteratingCallback.iterate(IteratingCallback.java:208)
at org.eclipse.jetty.client.ResponseNotifier.notifyContent(ResponseNotifier.java:117)
at org.eclipse.jetty.client.HttpReceiver.responseContent(HttpReceiver.java:322)
... 13 more
Questions:
Is there a way to avoid this buffering issue? (Maybe by using another component instead of jetty?)
Since the body is not changed in the jetty-endpoint I was wondering if it's possible to "bypass" the body directly to the next endpoint.
Using <to uri="http://localhost:55556/extract?restletMethod=PUT"/> fixed it for me.
Related
I am developing a sample route
FROM: SOURCE ENDPOINT URI
TO: TRANS ENDPOINT URI // Error or Exception occurred at this TRANS endpoint
TO: TARGET ENDPOINT URI
Now I want to catch the Error Occured endpoint and pass it to my processor.
Could anyone please help me with this?
<route>
<from uri="file:C:/MINTS/Source/"/>
<to uri="file:C:/MINTS/TRANS/"/> <!-- EXCPECTION OCCURED -->
<to uri="file:C:/MINTS/TARGET/"/>
<onException>
<exception>java.lang.Exception</exception>
<handled>
<constant>true</constant>
</handled>
<!-- NEED TO CATCH FAILURE ENDPOINT URI AND PASS TO MY PROCESSOR BELOW-->
<process ref="MyExceptionProcessor" />
</onException>
</route>
You can use exchange properties:
CamelFailureEndpoint
example xml-dsl: <exchangeProperty>CamelFailureEndpoint</exchangeProperty>
example java: exchange.getProperty(Exchange.FAILURE_ENDPOINT, String.class);
CamelToEndpoint
example xml-dsl: <exchangeProperty>CamelToEndpoint</exchangeProperty>
example java: exchange.getProperty(Exchange.TO_ENDPOINT, String.class)
The first one should print uri for the consumer endpoint (from) that failed and the second one should show the previously called producer (to) endpoint.
One handy way to debug contexts of an failed exchange is to use:
<to uri="log:loggerName?showAll=true" />
This will log all exchange properties, headers, body and exception which can help to understand what information is available within exchange. Be careful where you use it as it might also log secrets and passwords if they're within the exchange so better use it only locally during development.
For more information you'd probably need to access CamelMessageHistory exchange property through processor, bean or something.
I am new to Apache Camel. I am able to send JMS message from one queue to another queue. I would like to know how to handle the exception. I learned onException, But it is not working for me.
I changed my jms queue to jms1. However, when I execute the code i get an exception.
My expectation is whenever I get exception my bean class should be invoked, but it is not.
Exception:
org.apache.camel.RuntimeCamelException:
org.apache.camel.FailedToCreateRouteException: Failed to create route
route1 at: >>> To[jms1:queue:FinalQSource] <<< in route:
Route[[From[jms:queue:testQSource]] -> [OnException[[class j...
because of Failed to resolve endpoint: jms1://queue:FinalQSource due
to: No component found with scheme: jms1
Code
<camelContext id="jmsContext" xmlns="http://camel.apache.org/schema/spring">
<onException>
<exception>org.apache.camel.RuntimeCamelException</exception>
<exception>org.apache.camel.ResolveEndpointFailedException</exception>
<!-- <handled><constant>true</constant></handled> -->
<bean ref="exceptionListener" method="orderFailed" />
</onException>
<route>
<from uri="jms:queue:testQSource" />
<to uri="jms1:queue:FinalQSource" /><!--
</route>
</camelContext>
This will not work as the exception is being thrown by camel when it tries to parse your route. The onException block will only catch exceptions that are thrown during execution of your route.
To test exception handling use the proper camel testing guide - http://camel.apache.org/testing.html
I would recommend mocking one of your endpoints to return an exception, example here - https://github.com/christian-posta/camel-sandbox/blob/master/one-off/src/test/java/posta/TestMockExceptions.java
MockEndpoint mockException = MockEndpoint.resolve(context, "mock:exception");
mockException.whenAnyExchangeReceived(new Processor() {
#Override
public void process(Exchange exchange) throws Exception {
System.out.println("i got here...");
throw new RuntimeException("fail!");
}
});
I have a Camel route exposed as a CXF web service. This is a bottom up web service and has an operation like so:
List<Book> getBooks();
The CXF endpoint is defined as:
<cxf:cxfEndpoint id="bookService"
address="http://localhost:9045/bookservice"
serviceClass="org.test.cxfws.service.BookDBService">
</cxf:cxfEndpoint>
The operation queries a list of books and returns it to the caller. The Camel route looks like this:
<camel:camelContext xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="cxf:bean:bookService"/>
<choice>
<when>
<simple>${header.operationName} == 'getBooks'</simple>
<to uri="bean:wsImplBean?method=getBooks"/>
</when>
<to uri="log:outboundSoapResponse"/>
<choice>
</route>
</camel:camelContext>
After running the route, I am getting the following exception:
org.apache.cxf.interceptor.Fault: org.test.cxfws.service.Book cannot be cast to java.util.List
at org.apache.cxf.jaxws.interceptors.WrapperClassOutInterceptor.handleMessage(WrapperClassOutInterceptor.java:117)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
at org.apache.cxf.interceptor.OutgoingChainInterceptor.handleMessage(OutgoingChainInterceptor.java:77)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
...
Caused by: java.lang.ClassCastException: org.test.cxfws.service.Book cannot be cast to java.util.List
at org.test.cxfws.service.GetBooksResponse_WrapperTypeHelper1.createWrapperObject(Unknown Source)
at org.apache.cxf.jaxws.interceptors.WrapperClassOutInterceptor.handleMessage(WrapperClassOutInterceptor.java:101)
I can see that the getBooks method from the bean wsImpBean is executed and the result being returned at the end of the choice block inside the route:
[ qtp1653072092-14] outboundSoapResponse INFO Exchange[ExchangePattern: InOut, BodyType: java.util.ArrayList, Body: [org.test.cxfws.service.Book#63f1858b, org.test.cxfws.service.Book#5769bf0, org.test.cxfws.service.Book#2df7ac5d, org.test.cxfws.service.Book#5f55253e, org.test.cxfws.service.Book#4f003a57]]
Can someone help me to understand why the ClassCastException.
Thanks.
As camel-cxf use list to hold the response for handling the InOut parameters. When you set the response result into the message body, you need to wrap the result into a List just like this
List<Book> books ...
List<Object> resultList = new ArrayList<Object>();
resultList.add(books);
exchange.getOut().setBody(resultList);
i'm using camel to validate an xml and in the route I'm doing the following:
<route>
<from uri="file:{{file.inbox}}?preMove=inprogress&move=../.done"/>
<doTry>
<to uri="validator:classpath:idocOrderStatus.xsd"/>
<to uri="file:{{file.outbox.valid}}"/>
<doCatch>
<exception>org.apache.camel.ValidationException</exception>
<to uri="file:{{file.outbox.invalid}}"/>
</doCatch>
</doTry>
</route>
and I'm getting the following error:
Exception in thread "SpringOsgiExtenderThread-10" org.apache.camel.RuntimeCamelException: org.apache.camel.FailedToCreateRouteException: Failed to create route route7 at: >>> DoT
ry[[To[validator:classpath:idocOrderStatus.xsd], To[file:outbox/valid], DoCatch[ null -> [To[file:{{file.outbox.invalid}}]]]]] <<< in route: Route[[From[file:{{file.inbox}}?preMove=inprogres
s&move=../.... because of org.apache.camel.ValidationException
at org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:1157)
at org.apache.camel.spring.SpringCamelContext.onApplicationEvent(SpringCamelContext.java:110)
at org.apache.camel.spring.CamelContextFactoryBean.onApplicationEvent(CamelContextFactoryBean.java:240)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:97)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:303)
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:911)
at org.springframework.osgi.context.support.AbstractOsgiBundleApplicationContext.finishRefresh(AbstractOsgiBundleApplicationContext.java:235)
at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext$4.run(AbstractDelegatedExecutionApplicationContext.java:358)
at org.springframework.osgi.util.internal.PrivilegedUtils.executeWithCustomTCCL(PrivilegedUtils.java:85)
at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.completeRefresh(AbstractDelegatedExecutionApplicationContext.java:320)
at org.springframework.osgi.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor$CompleteRefreshTask.run(DependencyWaiterApplicationContextExecutor.java:
132)
at java.lang.Thread.run(Thread.java:662)
Caused by: org.apache.camel.FailedToCreateRouteException: Failed to create route route7 at: >>> DoTry[[To[validator:classpath:idocOrderStatus.xsd], To[file:outbox/valid], DoCatch[ null -> [T
o[file:{{file.outbox.invalid}}]]]]] <<< in route: Route[[From[file:{{file.inbox}}?preMove=inprogress&move=../.... because of org.apache.camel.ValidationException
at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:820)
at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:165)
at org.apache.camel.impl.DefaultCamelContext.startRoute(DefaultCamelContext.java:685)
at org.apache.camel.impl.DefaultCamelContext.startRouteDefinitions(DefaultCamelContext.java:1683)
at org.apache.camel.impl.DefaultCamelContext.doStartCamel(DefaultCamelContext.java:1468)
at org.apache.camel.impl.DefaultCamelContext.doStart(DefaultCamelContext.java:1360)
at org.apache.camel.spring.SpringCamelContext.doStart(SpringCamelContext.java:169)
at org.apache.camel.impl.ServiceSupport.start(ServiceSupport.java:67)
at org.apache.camel.impl.ServiceSupport.start(ServiceSupport.java:54)
at org.apache.camel.impl.DefaultCamelContext.start(DefaultCamelContext.java:1328)
at org.apache.camel.spring.SpringCamelContext.maybeStart(SpringCamelContext.java:213)
at org.apache.camel.spring.SpringCamelContext.onApplicationEvent(SpringCamelContext.java:108)
... 10 more
Caused by: java.lang.ClassNotFoundException: org.apache.camel.ValidationException
at org.apache.camel.impl.DefaultClassResolver.resolveMandatoryClass(DefaultClassResolver.java:52)
at org.apache.camel.model.CatchDefinition.createExceptionClasses(CatchDefinition.java:254)
at org.apache.camel.model.CatchDefinition.createProcessor(CatchDefinition.java:91)
at org.apache.camel.model.TryDefinition.createProcessor(TryDefinition.java:90)
at org.apache.camel.model.ProcessorDefinition.makeProcessor(ProcessorDefinition.java:444)
at org.apache.camel.model.ProcessorDefinition.addRoutes(ProcessorDefinition.java:183)
at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:817)
... 21 more
I do not understend why I'm getting this error? There is anyway to import this class in the camel context? How should I do it?
You can find the solution on the fuse forum fuse forum
I'm trying to retrieve the stacktrace from the onException handler in Apache Camel:
<onException>
<exception>java.lang.Exception</exception>
<handled>
<constant>true</constant>
</handled>
<setHeader headerName="exception">
<simple>${exception}</simple>
</setHeader>
</onException>
However, the above only shows the exception rather than the entire stacktrace.
I understand that Camel stores the caught exception as a property on the Exchange with the key: Exchange.EXCEPTION_CAUGHT, but how can this be retrieved from the camel context routes file ?
Use exception.stacktrace to get the stacktrace. See the variables listed in the table at this page: http://camel.apache.org/simple
<simple>${exception.stacktrace}</simple>
There is also a ${exception.message} to refer to the exception message itself.