Hi Aswin

After I went through your mail , I think you are already starting the servlet transport for CXF
by loading the bus with the CXF Servlet transport.

To be honestly , I do not write any test code for the WebServiceProvider in camel-cxf component. So you may meet some trouble when you start up the WebServiceProvider in camel context,
and patches are welcomed :)

Here is my suggestion for you:

If you just want to leverage the WebServiceProvider API in CXF to deal with the raw XML
message and let camel to do the routing work, you just can do like this.

1. Starting the CXF endpoint by call the JAXWS API (not by starting camel context in spring) 2. Then starting the camel context in your Provider implement code (you could start the camel
context here), and routing the message to various processors

Here are my answers for your questions in the mail
1) For the SEI
In camel-cxf component , we mainly use SEI to look for the type class information for XML message If you just use the WebServiceProvider , you just need to implement an invoke API in your implement
class. The business function could let invoke method to deal with.

2) For the Serlvet transport.
Since CXF will load the jetty engine to start up the http listener by default, you need to load the bus with CXF serlvet transport, you can went thought the CXF wiki[1] for more information.

Now, you already did it by letting the Spring configuration context import the

classpath:META-INF/cxf/cxf-servlet.xml

[1] http://cwiki.apache.org/CXF20DOC/index.html

Willem.

aswin.nair wrote:
Long Message Warning

Hello, First of all thanks for all the great work in Camel and CFX.

We are planning to use CXF as our service stack for a new project and I am
planning to use Camel for the routing needs. We use Tomcat as container and
would like to know the feasibility of the following
The CFX Web Service would be available through ServletTransport and with
SOAP binding and would like to use the WebServiceProvider (no default data
biding support) as we are planning to deal with the raw XML Message. Based
on the content I would then route the message to various processors and
external services(endpoints) and finally return the result to the request
client (soap or REST). I have a sample solution for this now with CXF
exposing a WebServiceProvider that would recieve the XML message and some
basic home grown routing logic that works with beans defined in Spring
context. I want to replace this part with Camel and is where I am
experiencing trouble.
As I understand CamelConsumer would inject a MessageObserver in the CXF
chain and this in turn would use CamelInvoker to invoke the route before it
request reaches the actual CXF endpoint. If this is right I could probably be able to get away having a WebServiceProvider SEI at all and have Camel
Processors do the job of routing the requests to all my bean processors and
external services (thrid party SOAP Services and such) .
Anyway I started integrating my existing CFX service with a very basic Camel
route with the following configuration and is loaded through a web
application in Tomcat using SpringContextLoader. My intention was to route
all incoming messages to the CFX endpoint to the bean processor or any other
provider and then finally invoke the SEI and return the output to the
requesting client.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans";
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
xmlns:jax="http://cxf.apache.org/jaxws"; xmlns:cxf="http://activemq.apache.org/camel/schema/cxfEndpoint";
        xmlns:camel="http://activemq.apache.org/camel/schema/spring";
        xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://activemq.apache.org/camel/schema/cxfEndpoint
http://activemq.apache.org/camel/schema/cxf/cxfEndpoint.xsd
        http://activemq.apache.org/camel/schema/spring
http://activemq.apache.org/camel/schema/spring/camel-spring.xsd";>
<import resource="classpath:META-INF/cxf/cxf.xml"/>
        <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" /> <cxf:cxfEndpoint id="SimpleServiceEndpoint" serviceClass="org.aswin.services.SimpleServicesProvider" address="/SimpleService"
wsdlURL="file:///c:/workspaces/Trials3.0/CXFCamel/WebContent/WEB-INF/wsdl/SimpleService.wsdl"
                                 
endpointName="s:SimpleWebServicePort" serviceName="s:SimpleWebService" xmlns:s="http://services.aswin.org/soap"; > </cxf:cxfEndpoint>
        <bean id="testProcessor" class="com.aswin.camel.TestProcessor"></bean>
        <bean id="second" class="com.aswin.camel.SecondBean"></bean>

        <camel:camelContext id="camel"
xmlns="http://activemq.apache.org/camel/schema/spring";>
<camel:route> <camel:from uri="cxf:bean:SimpleServiceEndpoint" />
                        <!-- camel:bean ref="second"></camel:bean-->            
          
<camel:process ref="testProcessor"></camel:process> </camel:route>
        </camel:camelContext>
</beans>

While starting the application I get the following in Tomcat logs
SEVERE: Context initialization failed
org.apache.camel.RuntimeCamelException:
org.apache.camel.ResolveEndpointFailedException: Failed to resolve endpoint:
cxf:bean:SimpleServiceEndpoint due to:
org.apache.camel.RuntimeCamelException: Could not auto create component: cxf
        at
org.apache.camel.spring.SpringCamelContext.onApplicationEvent(SpringCamelContext.java:98)
        at
org.springframework.context.event.SimpleApplicationEventMulticaster$1.run(SimpleApplicationEventMulticaster.java:78)
        at
org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:49)
        at
org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:76)
        at
org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:260)
        at
org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:744)
        at
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:372)
        at
org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:261)
        at
org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:199)
        at
org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:45)
        at
org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3764)
        at
org.apache.catalina.core.StandardContext.start(StandardContext.java:4216)
        at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1014)
        at org.apache.catalina.core.StandardHost.start(StandardHost.java:736)
        at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1014)
        at 
org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
        at 
org.apache.catalina.core.StandardService.start(StandardService.java:448)
        at 
org.apache.catalina.core.StandardServer.start(StandardServer.java:700)
        at org.apache.catalina.startup.Catalina.start(Catalina.java:552)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:585)
        at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:295)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:433)
Caused by: org.apache.camel.ResolveEndpointFailedException: Failed to
resolve endpoint: cxf:bean:SimpleServiceEndpoint due to:
org.apache.camel.RuntimeCamelException: Could not auto create component: cxf
        at
org.apache.camel.impl.DefaultCamelContext.getEndpoint(DefaultCamelContext.java:279)
        at
org.apache.camel.util.CamelContextHelper.getMandatoryEndpoint(CamelContextHelper.java:51)
        at org.apache.camel.model.RouteType.resolveEndpoint(RouteType.java:80)
        at 
org.apache.camel.impl.RouteContext.resolveEndpoint(RouteContext.java:96)
        at
org.apache.camel.impl.RouteContext.resolveEndpoint(RouteContext.java:105)
        at org.apache.camel.model.FromType.resolveEndpoint(FromType.java:67)
        at org.apache.camel.impl.RouteContext.getEndpoint(RouteContext.java:71)
        at org.apache.camel.model.RouteType.addRoutes(RouteType.java:170)
        at org.apache.camel.model.RouteType.addRoutes(RouteType.java:71)
        at
org.apache.camel.impl.DefaultCamelContext.startRouteDefinitions(DefaultCamelContext.java:455)
        at
org.apache.camel.impl.DefaultCamelContext.doStart(DefaultCamelContext.java:447)
        at
org.apache.camel.spring.SpringCamelContext.doStart(SpringCamelContext.java:140)
        at org.apache.camel.impl.ServiceSupport.start(ServiceSupport.java:51)
        at
org.apache.camel.spring.SpringCamelContext.onApplicationEvent(SpringCamelContext.java:96)
        ... 24 more
Caused by: org.apache.camel.RuntimeCamelException: Could not auto create
component: cxf
        at
org.apache.camel.impl.DefaultCamelContext.getComponent(DefaultCamelContext.java:153)
        at
org.apache.camel.impl.DefaultCamelContext.getEndpoint(DefaultCamelContext.java:256)
        ... 37 more
Caused by: java.lang.IllegalArgumentException: Bean with name: cxf in
registry is not a Component: [EMAIL PROTECTED]
        at
org.apache.camel.impl.DefaultComponentResolver.resolveComponent(DefaultComponentResolver.java:57)
        at
org.apache.camel.impl.DefaultCamelContext.getComponent(DefaultCamelContext.java:142)
        ... 38 more

As the message clearly says the CXF imports defines the default cxf bus with
name "cxf" and camel tries to use th same name for the routing reference.
Anyways if I comment out the CXF imports(just to get it to start) allowing
Camel to create the bus for me, I get the following error
WARNING: Could not find a matching method for operation
{http://services.aswin.org/soap}genericOperation. Operation will be
unavailable.
org.apache.cxf.service.factory.ServiceConstructionException
        at
org.apache.cxf.frontend.ServerFactoryBean.create(ServerFactoryBean.java:128)
        at 
org.apache.camel.component.cxf.CxfConsumer.<init>(CxfConsumer.java:90)
        at
org.apache.camel.component.cxf.CxfEndpoint.createConsumer(CxfEndpoint.java:79)
        at
org.apache.camel.impl.EventDrivenConsumerRoute.addServices(EventDrivenConsumerRoute.java:62)
        at org.apache.camel.Route.getServicesForRoute(Route.java:75)
        at
org.apache.camel.impl.DefaultCamelContext.startRoutes(DefaultCamelContext.java:473)
        at
org.apache.camel.impl.DefaultCamelContext.doStart(DefaultCamelContext.java:448)
        at
org.apache.camel.spring.SpringCamelContext.doStart(SpringCamelContext.java:140)
        at org.apache.camel.impl.ServiceSupport.start(ServiceSupport.java:51)
        at
org.apache.camel.spring.SpringCamelContext.onApplicationEvent(SpringCamelContext.java:96)
        at
org.springframework.context.event.SimpleApplicationEventMulticaster$1.run(SimpleApplicationEventMulticaster.java:78)
        at
org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:49)
        at
org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:76)
        at
org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:260)
        at
org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:744)
        at
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:372)
        at
org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:261)
        at
org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:199)
        at
org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:45)
        at
org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3764)
        at
org.apache.catalina.core.StandardContext.start(StandardContext.java:4216)
        at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1014)
        at org.apache.catalina.core.StandardHost.start(StandardHost.java:736)
        at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1014)
        at 
org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
        at 
org.apache.catalina.core.StandardService.start(StandardService.java:448)
        at 
org.apache.catalina.core.StandardServer.start(StandardServer.java:700)
        at org.apache.catalina.startup.Catalina.start(Catalina.java:552)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:585)
        at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:295)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:433)
Caused by: org.apache.cxf.BusException: No DestinationFactory was found for
the namespace http://schemas.xmlsoap.org/soap/http.
        at
org.apache.cxf.transport.DestinationFactoryManagerImpl.getDestinationFactory(DestinationFactoryManagerImpl.java:106)
        at 
org.apache.cxf.endpoint.ServerImpl.initDestination(ServerImpl.java:85)
        at org.apache.cxf.endpoint.ServerImpl.<init>(ServerImpl.java:69)
        at
org.apache.cxf.frontend.ServerFactoryBean.create(ServerFactoryBean.java:109)
        ... 33 more

I reverted the CXF imports and edited the
camel-cxf-1.3-20080206.031608-65.jar  and renamed teh CXFComponent file
(META-INF\services\org\apache\camel\component\cxf) to camelcxf and changed
the routes to reflect the new name as follows <camel:camelContext id="camel"
xmlns="http://activemq.apache.org/camel/schema/spring";>
<camel:route> <camel:from uri="camelcxf:bean:SimpleServiceEndpoint" />
                        <!-- camel:bean ref="second"></camel:bean-->            
          
<camel:process ref="testProcessor"></camel:process> </camel:route>
        </camel:camelContext>


After this change (and with the existing CXF imports) my web application
started without errors. But I noticed that CXF was building my service from
WSDL and was not using Jax-WS WebServiceProvider. A quick look at the source
told me that ServerFactoryBean created by the consumer is not a
JaxWsServerFactoryBean as the CxfEndpointUtils.hasWebServiceAnnotation(cls)
method just checks for the WebService annotation and does not consider the
WebServiceProvider annotation. Without changing anything if I try to invoke
the WebSerice (using SOAP UI) I get a Soap Fault with the message <soap:Fault>
         <faultcode>soap:Client</faultcode>
         <faultstring>Message part
{http://simple.services.aswin.org/data}SimpleWebServiceRequest was not
recognized.</faultstring>
      </soap:Fault>

I can get past the errors if I modify the CxfEndUtils or change my SEI to be
a WebService instead of a WebServiceProvider and am able to get the Camel
Route running. But I hit some exceptions a and decided that I seek help so
that I could find a solution faster

In specific I have the following questions
1) Do we need a SEI at all or could we use Camel to intercept a request for
a Abstract SEI definition and fullfill the role of the SEI. I could have
multiple small services and processors cordinated by CAMEL in realizing the
business function.

2) Do we need any specific configuration to enable Servlet Transport and
interception of Messages? How could I setup the interceptor route for
handling messages? And is there any specific routing or configuration needed
for returning the results to the end client (two way channel?)

3) Any other thoughts on this.

Any help would be really appreciated
Thanks
Aswin






Reply via email to