You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by "aswin.nair" <ma...@gmail.com> on 2008/02/08 07:25:07 UTC

Camel CXF Spring Tomcat configuration

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: org.apache.cxf.bus.CXFBusImpl@d2d58b
	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





-- 
View this message in context: http://www.nabble.com/Camel-CXF-Spring-Tomcat-configuration-tp15350144s22882p15350144.html
Sent from the Camel - Users mailing list archive at Nabble.com.


Re: Camel CXF Spring Tomcat configuration

Posted by "aswin.nair" <ma...@gmail.com>.

willem.jiang wrote:
> 
> Thank you for your contribution. I got your patch and am working on it.
> "svn diff " only show the difference of the files under the control, so 
> you need to use "svn add" to add the newly added files.
> And you could create a new JIRA to submit the patch that we can keep the 
> track of it.
> 
 Figured that out just after sending you the mail and the examples patch was
created like that.


willem.jiang wrote:
> 
> AFAIK, we do not need to add check if the SEI is the webservice provider.
> I will add a unit test for the camel-cxf component against your patch to 
> test for that.
> 
Yes, we don't have to and the example also does not. It just uses a
WebServiceProvider at the server end for configuration and at client end
uses the Dispatch API and also shows routing from the endpoint to a simple
bean.  
Thanks a lot for all the help. Camel rocks!!!!!!!  :-D
Aswin

-- 
View this message in context: http://www.nabble.com/Camel-CXF-Spring-Tomcat-configuration-tp15350144s22882p15456858.html
Sent from the Camel - Users mailing list archive at Nabble.com.


Re: Camel CXF Spring Tomcat configuration

Posted by Willem Jiang <wi...@gmail.com>.
Hi Aswin,

Thank you for your contribution. I got your patch and am working on it.
"svn diff " only show the difference of the files under the control, so 
you need to use "svn add" to add the newly added files.
And you could create a new JIRA to submit the patch that we can keep the 
track of it.

AFAIK, we do not need to add check if the SEI is the webservice provider.
I will add a unit test for the camel-cxf component against your patch to 
test for that.

Willem.


aswin.nair wrote:
> Hello Willem,
>
>
> willem.jiang wrote:
>   
>> Here are some points that I want to say about the patch:
>> 1. You need to create a JIRA[1] to submit the patch and grant it with 
>> ASF license otherwise I can't applied it.
>> 2. Please using the "svn diff  > path "command to create the patch. It 
>> will generate the patch file will relate patch.
>> 3. I notice you remove the cxf component META_INF description file, but 
>> do not add a new one for that.
>>
>> BTW,  I will start a new thread to discuss whether we need to change the 
>> cxf component's URI prefix "cxf" to avoid the "cxf" bus conflict  in the 
>> spring context.
>> [1]https://issues.apache.org/activemq/browse/CAMEL
>>
>>     
>
> I have created  https://issues.apache.org/activemq/browse/CAMEL-332 Jira
> issue 332  for this and have submitted the patch there as you wanted me to.
> I reverted the change done renaming the cfx component in META_INF as I saw
> it was getting worked on now.
> I have created a new set of examples for the webservice provider based
> configuration that routes the call to a simple bean. Where do I submit those
> files to? I am not able to get a svn diff for the newly added files, how do
> I do that?
>   


Re: Camel CXF Spring Tomcat configuration

Posted by "aswin.nair" <ma...@gmail.com>.
Hello Willem,


willem.jiang wrote:
> 
> Here are some points that I want to say about the patch:
> 1. You need to create a JIRA[1] to submit the patch and grant it with 
> ASF license otherwise I can't applied it.
> 2. Please using the "svn diff  > path "command to create the patch. It 
> will generate the patch file will relate patch.
> 3. I notice you remove the cxf component META_INF description file, but 
> do not add a new one for that.
> 
> BTW,  I will start a new thread to discuss whether we need to change the 
> cxf component's URI prefix "cxf" to avoid the "cxf" bus conflict  in the 
> spring context.
> [1]https://issues.apache.org/activemq/browse/CAMEL
> 

I have created  https://issues.apache.org/activemq/browse/CAMEL-332 Jira
issue 332  for this and have submitted the patch there as you wanted me to.
I reverted the change done renaming the cfx component in META_INF as I saw
it was getting worked on now.
I have created a new set of examples for the webservice provider based
configuration that routes the call to a simple bean. Where do I submit those
files to? I am not able to get a svn diff for the newly added files, how do
I do that?
-- 
View this message in context: http://www.nabble.com/Camel-CXF-Spring-Tomcat-configuration-tp15350144s22882p15449546.html
Sent from the Camel - Users mailing list archive at Nabble.com.


Re: Camel CXF Spring Tomcat configuration

Posted by Willem Jiang <wi...@gmail.com>.
Hi Aswin,

I got your patch, it gets the WebServiceProvider work. That is why I 
love open source , people can elaborate the software  across the world :).

Since CXF also provides the simple front end to provides Web Services 
implementation, I still need to use the CXF's ServerFactoryBean API to 
create the CXF Endpoint for handling the MESSAGE/PAYLOAD message. 
Basically,
they are the same thing that you got from the WebServiceProvider which 
skip some interceptors which are used for POJO invocation.

Here are some points that I want to say about the patch:
1. You need to create a JIRA[1] to submit the patch and grant it with 
ASF license otherwise I can't applied it.
2. Please using the "svn diff  > path "command to create the patch. It 
will generate the patch file will relate patch.
3. I notice you remove the cxf component META_INF description file, but 
do not add a new one for that.

BTW,  I will start a new thread to discuss whether we need to change the 
cxf component's URI prefix "cxf" to avoid the "cxf" bus conflict  in the 
spring context.

[1]https://issues.apache.org/activemq/browse/CAMEL

Willem

aswin.nair wrote:
> Hello Willem,
>   Thanks for the reply. I was playing around with this stuff and tried some
> minor changes to the CXFConsumer and CXFInvoker to deal with the
> WebServiceProvider annotation and work accordingly. I could get it to work
> and have some thoughts on this.  Since WebServiceProvider is the JAX-WS
> standard way of dealing with message/payload directly, couldn't we make the
> WebServiceProvider endpoint the default way of dealing with Message/Payload
> mode.   So a camel CXFEndpoint that needs to receive the data in
> message/payload mode would just have to declare a SEI with
> @WebServiceProvider annotation and  the camel route would be invoked with
> the specified format .  From camel side, this would mean that we would let
> CXF do all the message construction job and finally call the CamleInvoker
> for dispatching to the camel route using the modified CamelInvoker. I am
> sending you a patch file with the changes I made, please have a look and let
> me know what you think. 
>
> Aswin
>
>
>   


Re: Camel CXF Spring Tomcat configuration

Posted by "aswin.nair" <ma...@gmail.com>.
Hello Willem,
  Thanks for the reply. I was playing around with this stuff and tried some
minor changes to the CXFConsumer and CXFInvoker to deal with the
WebServiceProvider annotation and work accordingly. I could get it to work
and have some thoughts on this.  Since WebServiceProvider is the JAX-WS
standard way of dealing with message/payload directly, couldn't we make the
WebServiceProvider endpoint the default way of dealing with Message/Payload
mode.   So a camel CXFEndpoint that needs to receive the data in
message/payload mode would just have to declare a SEI with
@WebServiceProvider annotation and  the camel route would be invoked with
the specified format .  From camel side, this would mean that we would let
CXF do all the message construction job and finally call the CamleInvoker
for dispatching to the camel route using the modified CamelInvoker. I am
sending you a patch file with the changes I made, please have a look and let
me know what you think. 

Aswin


-- 
View this message in context: http://www.nabble.com/Camel-CXF-Spring-Tomcat-configuration-tp15350144s22882p15417089.html
Sent from the Camel - Users mailing list archive at Nabble.com.


Re: Camel CXF Spring Tomcat configuration

Posted by Willem Jiang <wi...@gmail.com>.
Hi Aswin

My comments are in the mail.
aswin.nair wrote:
> Hello Willem,
>   
>
> willem.jiang wrote:
>   
>> 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.
>>
>>     
>  Yes I had the servlet transport working after I changed the service name of
> the Camel CXF component from cfx to camelcfx. I think we can configure the
> endpoints using the camel configuration for that, but if we need to import
> the default CXF configurations we may have the conflict. 
>   
[Willem] I got that , since "cxf" is used for the CXF bus instance in 
the Spring context ,we need to resolve
 the conflict of cxf and camel-cxf component.
>
> willem.jiang wrote:
>   
>> 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 :)
>>
>>     
> Sure. 
>
>
> willem.jiang wrote:
>   
>> 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
>>
>>     
> We already have a similar thing, but I think the approach like what you have
> for the WebService SEI would be really nice as the routes would be more
> descriptive.
>   
[Willem] Can you show me the SEI that you have in your project?
camel-cxf consumer component pass the message to the router in three 
different
 data formate. 
They are PAYLOAD, MESSAGE, POJO
You can find the more information by reading the comments in the 
DataFormat.java[1]
[1]https://svn.apache.org/repos/asf/activemq/camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/DataFormat.java

Now I am working on the refactoring work CAMEL-312 [2] , and if you have any
 requirement please free to add comment on the JIRA
[2]https://issues.apache.org/activemq/browse/CAMEL-312
>
> willem.jiang wrote:
>   
>> 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.
>>
>>     
> Okay. This was the stuff confusing me and now I got it. So the SEI method
> would not be invoked (by default) by Camel but instead be forwarded to the
> route. I think the same could be done for the WebServiceProvider SEIs also
> with some minor modifications to Camel CXF classes. 
>
>
>   
[Willem] I think we need to make the SEI more clear.
It just is an interface and CXF will delegate to the SEI implementor 
when it received a SOAP request.
For camel-cxf component, the CXF endpoint consumer will delegate the 
request to the camel router
 processors.


For the WebServcieProvider , the SEI just have one invoke method and we 
skip the the XML
unmarshal and marshal processing in CXF. In this case we do not need to 
use the type classes to
do the data bind work.
> willem.jiang wrote:
>   
>> 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
>>
>>     
> Yes, this would work, but we have to change the service name of the CFX
> component to be something other than "cfx". Alternatively I think we can
> create a new cfx-configuration file with different names for the default bus
> and referring that like following 
>  	<cxf:cxfEndpoint id="SimpleServiceEndpoint" 
>  	        serviceClass="org.aswin.services.SimpleServicesProvider"
>  			address="/SimpleService" 	    
>     		wsdlURL="WEB-INF/wsdl/SimpleService.wsdl"    		     		
>     		endpointName="s:SimpleWebServicePort" 
>     		serviceName="s:SimpleWebService"     		  
>     	    xmlns:s="http://services.aswin.org/soap"
>     	    bus="newbus" >    	     
>     </cxf:cxfEndpoint>     
>
> Please correct me if I wrong in any of these. I would try making changes to
> the Camel CXF classes if you think it would be a good thing to have.
>
>   
[Willem]
Setting the cxfEndpoint bus with another bus instance is a way to do it 
. Because there are lots of CXF
 component which injected into the "cxf" bus , so it is not easy way to 
do it.

> Thanks
> Aswin
>
>
>   
Willem.

Re: Camel CXF Spring Tomcat configuration

Posted by "aswin.nair" <ma...@gmail.com>.
Hello Willem,
  

willem.jiang wrote:
> 
> 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.
> 
 Yes I had the servlet transport working after I changed the service name of
the Camel CXF component from cfx to camelcfx. I think we can configure the
endpoints using the camel configuration for that, but if we need to import
the default CXF configurations we may have the conflict. 


willem.jiang wrote:
> 
> 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 :)
> 
Sure. 


willem.jiang wrote:
> 
> 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
> 
We already have a similar thing, but I think the approach like what you have
for the WebService SEI would be really nice as the routes would be more
descriptive.


willem.jiang wrote:
> 
> 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.
> 
Okay. This was the stuff confusing me and now I got it. So the SEI method
would not be invoked (by default) by Camel but instead be forwarded to the
route. I think the same could be done for the WebServiceProvider SEIs also
with some minor modifications to Camel CXF classes. 



willem.jiang wrote:
> 
> 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
> 
Yes, this would work, but we have to change the service name of the CFX
component to be something other than "cfx". Alternatively I think we can
create a new cfx-configuration file with different names for the default bus
and referring that like following 
 	<cxf:cxfEndpoint id="SimpleServiceEndpoint" 
 	        serviceClass="org.aswin.services.SimpleServicesProvider"
 			address="/SimpleService" 	    
    		wsdlURL="WEB-INF/wsdl/SimpleService.wsdl"    		     		
    		endpointName="s:SimpleWebServicePort" 
    		serviceName="s:SimpleWebService"     		  
    	    xmlns:s="http://services.aswin.org/soap"
    	    bus="newbus" >    	     
    </cxf:cxfEndpoint>     

Please correct me if I wrong in any of these. I would try making changes to
the Camel CXF classes if you think it would be a good thing to have.

Thanks
Aswin


-- 
View this message in context: http://www.nabble.com/Camel-CXF-Spring-Tomcat-configuration-tp15350144s22882p15367833.html
Sent from the Camel - Users mailing list archive at Nabble.com.


Re: Camel CXF Spring Tomcat configuration

Posted by Willem Jiang <wi...@gmail.com>.
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: org.apache.cxf.bus.CXFBusImpl@d2d58b
> 	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
>
>
>
>
>
>