I'm having issues with camel http4 endpoint - apache-camel

Spring context:
<bean id="customRouteA" class="com.xxx.CustomRouteABean" />
<camelContext id="solr" xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="activemq:topic:agent" />
<to uri="bean:customRouteA"/>
</route>
</camelContext>
Java code:
public class CustomRouteABean {
#EndpointInject(uri = "http4://localhost/camel-route-test.php")
ProducerTemplate producer;
public void processMessage(#Body String message) {
...
}
}
Keeps getting error:
2085 [main] ERROR org.springframework.web.context.ContextLoader - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customRouteA' defined in ServletContext resource [/WEB-INF/application-context.xml]: Initialization of bean failed; nested exception is org.apache.camel.spring.GenericBeansException: Error post processing bean: customRouteA; nested exception is org.apache.camel.ResolveEndpointFailedException: Failed to resolve endpoint: http4://localhost/camel-route-test.php?bridgeEndpoint=true due to: null
I have another bean has the same setup works just fine, what am I missing here?

And you have camel-http4 and its dependent JARs on the classpath?

Related

org.apache.camel.NoSuchBeanException for error handler mapped to route

I have the following route definitions file (linehaul-routes.xml):
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://camel.apache.org/schema/spring"
xsi:schemaLocation="
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd">
<route id="route1" errorHandlerRef="myErrorHandler">
<from uri="amqp:queue:DSMLH_consignment_event"/> <!-- AMQP queue to which I send messages to trigger the route !-->
<to uri="https://pesho.free.beeceptor.com/"/> <!-- Returns http 500 !-->
</route>
</routes>
I also have a file with error handler in the same directory (linehaul-error-handlers.xml):
<errorHandlers>
<errorHandler id="myErrorHandler" type="DefaultErrorHandler">
<redeliveryPolicy maximumRedeliveries="5" redeliveryDelay="2000"/>
</errorHandler>
</errorHandlers>
And application.properties
camel.context.name=testContext
camel.main.routes-include-pattern=classpath:routes/linehaul-routes.xml,classpath:routes/linehaul-error-handlers.xml
When I run the code I get the following stacktrace
2022-04-27 19:44:53,657 ERROR [org.apa.cam.qua.mai.CamelMainRuntime] (Quarkus Main Thread) [{}] Failed to start application: org.apache.camel.FailedToCreateRouteException: Failed to create route route1 at: >>> To[https://pesho.free.beeceptor.com/] <<< in route: Route(route1)[From[amqp:queue:DSMLH_consignment_event] -> [T... because of No bean could be found in the registry for: myErrorHandler of type: org.apache.camel.ErrorHandlerFactory
at org.apache.camel.reifier.RouteReifier.doCreateRoute(RouteReifier.java:240)
at org.apache.camel.reifier.RouteReifier.createRoute(RouteReifier.java:74)
at org.apache.camel.impl.DefaultModelReifierFactory.createRoute(DefaultModelReifierFactory.java:49)
at org.apache.camel.impl.DefaultCamelContext.startRouteDefinitions(DefaultCamelContext.java:868)
at org.apache.camel.impl.DefaultCamelContext.startRouteDefinitions(DefaultCamelContext.java:758)
at org.apache.camel.impl.engine.AbstractCamelContext.doInit(AbstractCamelContext.java:2862)
at org.apache.camel.quarkus.core.FastCamelContext.doInit(FastCamelContext.java:166)
at org.apache.camel.support.service.BaseService.init(BaseService.java:83)
at org.apache.camel.impl.engine.AbstractCamelContext.init(AbstractCamelContext.java:2568)
at org.apache.camel.support.service.BaseService.start(BaseService.java:111)
at org.apache.camel.impl.engine.AbstractCamelContext.start(AbstractCamelContext.java:2587)
at org.apache.camel.impl.DefaultCamelContext.start(DefaultCamelContext.java:247)
at org.apache.camel.quarkus.main.CamelMain.doStart(CamelMain.java:94)
at org.apache.camel.support.service.BaseService.start(BaseService.java:119)
at org.apache.camel.quarkus.main.CamelMain.startEngine(CamelMain.java:140)
at org.apache.camel.quarkus.main.CamelMainRuntime.start(CamelMainRuntime.java:49)
at org.apache.camel.quarkus.core.CamelBootstrapRecorder.start(CamelBootstrapRecorder.java:45)
at io.quarkus.deployment.steps.CamelBootstrapProcessor$boot173480958.deploy_0(Unknown Source)
at io.quarkus.deployment.steps.CamelBootstrapProcessor$boot173480958.deploy(Unknown Source)
at io.quarkus.runner.ApplicationImpl.doStart(Unknown Source)
at io.quarkus.runtime.Application.start(Application.java:101)
at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:103)
at io.quarkus.runtime.Quarkus.run(Quarkus.java:67)
at io.quarkus.runtime.Quarkus.run(Quarkus.java:41)
at io.quarkus.runtime.Quarkus.run(Quarkus.java:120)
at io.quarkus.runner.GeneratedMain.main(Unknown Source)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at io.quarkus.runner.bootstrap.StartupActionImpl$1.run(StartupActionImpl.java:103)
at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: org.apache.camel.NoSuchBeanException: No bean could be found in the registry for: myErrorHandler of type: org.apache.camel.ErrorHandlerFactory
at org.apache.camel.support.CamelContextHelper.mandatoryLookup(CamelContextHelper.java:241)
at org.apache.camel.model.errorhandler.ErrorHandlerHelper.lookupErrorHandlerFactory(ErrorHandlerHelper.java:82)
at org.apache.camel.reifier.errorhandler.ErrorHandlerRefReifier.lookupErrorHandler(ErrorHandlerRefReifier.java:41)
at org.apache.camel.reifier.errorhandler.ErrorHandlerRefReifier.createErrorHandler(ErrorHandlerRefReifier.java:35)
at org.apache.camel.impl.DefaultModelReifierFactory.createErrorHandler(DefaultModelReifierFactory.java:65)
at org.apache.camel.reifier.ProcessorReifier.wrapInErrorHandler(ProcessorReifier.java:745)
at org.apache.camel.reifier.ProcessorReifier.wrapChannelInErrorHandler(ProcessorReifier.java:726)
at org.apache.camel.reifier.ProcessorReifier.wrapChannel(ProcessorReifier.java:705)
at org.apache.camel.reifier.ProcessorReifier.wrapChannel(ProcessorReifier.java:611)
at org.apache.camel.reifier.ProcessorReifier.wrapProcessor(ProcessorReifier.java:607)
at org.apache.camel.reifier.ProcessorReifier.makeProcessor(ProcessorReifier.java:854)
at org.apache.camel.reifier.ProcessorReifier.addRoutes(ProcessorReifier.java:579)
at org.apache.camel.reifier.RouteReifier.doCreateRoute(RouteReifier.java:236)
... 31 more
What is wrong with the route to error handler mapping ?
(My goal is to make my route to re-try several times on http 500)
Camel Quarkus only supports 'simple' XML routes. You cannot define beans directly like you can with Camel Spring XML.
Instead, you can declare a CDI bean and reference it in the XML. For example.
#Named("myErrorHandler")
public DefaultErrorHandlerBuilder createDefaultErrorHandler() {
return new DefaultErrorHandlerBuilder()
.maximumRedeliveries(5)
.redeliveryDelay(2000);
}
Then you can reference the bean via errorHandlerRef on the route tag.
<route id="route1" errorHandlerRef="myErrorHandler">

How to properly handle Exceptions in Apache Camel using OnException

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!");
}
});

Getting ClassCastException in Camel route while handling response containing java.util.List

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);

CXF SOAP Fault handling

I am new to Camel and CXF. I am trying to post process the fault messages that are thrown from my Web Service. But CXF throws them as Fault exception only and hence the camel routing is aborted and the error handler is invoked.
How can I tweak Camel or CXF to get the fault message just as received by the CXF itself?
Is there any configuration by which I can attain this?
Or Do I need to provide an Interceptor to achieve this?
Or Do I need to handle in Error handler?
You can try this:
from("endpoint")
.doTry()
.to("endpoint")
.doCatch()
.process(new Processor(
#Override
public void process(Exchange exchange) throws Exception {
//Get the exception
SoapFault fault = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, SoapFault.class);
//Then you can change the body
}
))
.endDoTry()
.end();
This is the sample route in spring DSL. You can try this. This will perfectly work if there is SOAP Fault from the provider.
<route id="test-route-id">
<from uri="direct:from-route"/>
<doTry>
<log message="Request Payload : ${body}" loggingLevel="INFO" logName="test-route-id"/>
<to uri="direct:cxf-endpoint"/>
<log message="Response Payload : ${body}" loggingLevel="INFO" logName="test-route-id"/>
<doCatch>
<exception>org.apache.cxf.binding.soap.SoapFault</exception>
<to uri="direct:fault-handling-route"/>
</doCatch>
</doTry>
</route>
If you only want to react on faults you can do:
onException(Fault.class).handled(true).process(new MyFaltProcessor()).stop();

Error in validation in camel route

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

Resources