You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by awilliams <as...@mac.com> on 2016/08/09 18:55:56 UTC

Calling one web service from another

Hi,

I'm attempting to connect three routes together as shown below, but the
problem is that the very first incoming web service endpoint has a different
return type than a later web service that I call (but has the same
parameter). I therefore get an exception on calling the second web service
that says the return type should be "MyResponse" and not "MyResults" - ie it
somehow thinks I'm adhering to the method signature of the first web
service. The routes and error are described further below.

The problem seems to be that I can't persuade Camel to forget the web
service method signature from the original request and it seems to propagate
into the message queue and then into the Route 3 web service call. I've done
some digging and cxf uses something called continuations stored in the
attributes of the http request. I know route 3 works because I'm able to
call it directly from soapui without any issue. Debugging into
AbstractHttpDestination.invoke() I can see that the direct Soapui call
results in a new soap message getting created (good), whereas the call from
route 2 finds an existing continuation soap message on the
httpservletrequest and tries to reuse that (bad).

I've tried to clear out the headers in route 2 before I make the final call
in an attempt to get cxf to forget the original web service call but with no
luck. I can't believe this should be that fiddly to get to work and so I'm
probably missing something fundamental :-/

Thanks!
Ash

Route 1
Description: Web service accepts requests and places them on a queue,
returning a simple response
Exposes WS Signature: MyResponse makeRequest(MyRequest request)

Route 2
Description: Consumes requests from queue and submits them to route 3 via
web service
Invokes WS Signature: MyResult makeRequest(MyRequest request)

Route 3
Route Description: Web service that fulfils request by executing the report
and returning results
Exposes WS Signature: MyResult makeRequest(MyRequest request) 

	<camelContext id="camelContext"
xmlns="http://camel.apache.org/schema/spring">
		<route id="Route 1">
			<from uri="cxf:bean:inboundRequest" />
			<convertBodyTo type="uk.co.acme.bdm._1.MyRequest" />
			<marshal>
				<jaxb contextPath="uk.co.acme.bdm._1" />
			</marshal>
			<to uri="activemq:queue:SupplyReportRequests" pattern="InOnly" />
			<bean ref="reportRequestBean" />
		</route>

		<route id="Route 2">
			<from uri="activemq:queue:SupplyReportRequests" />
			<unmarshal>
				<jaxb contextPath="uk.co.acme.bdm._1" />
			</unmarshal>
			<to uri="cxf:bean:inboundExecute" />
		</route>

		<route id="Route 3">
			<from uri="cxf:bean:inboundExecute" />
			<bean ref="reportExecuteBean" />
		</route>
	</camelContext>
	
	
Caused by: org.apache.cxf.binding.soap.SoapFault: Part
{urn:acme.co.uk:bdm:1.0}requestResponse should be of type
uk.co.acme.bdm._1.MyResponse, not uk.co.acme.bdm._1.MyResults
	at
org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.unmarshalFault(Soap11FaultInInterceptor.java:86)
	at
org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:52)
	at
org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:41)
	at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
	at
org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:112)
	at
org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:69)
	at
org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:34)
	at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
	at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:780)
	at
org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1670)
	at
org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream$1.run(HTTPConduit.java:1168)
	at
org.apache.cxf.workqueue.AutomaticWorkQueueImpl$3.run(AutomaticWorkQueueImpl.java:428)
	at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at
org.apache.cxf.workqueue.AutomaticWorkQueueImpl$AWQThreadFactory$1.run(AutomaticWorkQueueImpl.java:353)
	... 1 more




--
View this message in context: http://camel.465427.n5.nabble.com/Calling-one-web-service-from-another-tp5786218.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Chaining web service calls in a route

Posted by awilliams <as...@mac.com>.
I've now resolved this. The problem was that the web service consists of two
operations and for some reason when I called the producer endpoint it was
selecting the first operation by default - same parameter but different
return value.

Therefore all I had to do was to tell Camel explicitly which operation I
wanted to be called by setting the appropriate header:

    <route id="Request: Store Request">
            <from uri="cxf:bean:inboundRequest" /> (signature = "MyResponse
request(MyRequest)") 
                
            <setHeader headerName="operationName">
                <constant>execute</constant>
            </setHeader> 
        
            <to uri="cxf:bean:inboundExecute" /> (signature = "MyResults
execute(MyRequest)") 
    </route>

I'm guessing that if my web service operations would have had different
parameter types then camel/cxf would have been able to work out which one to
call without me having to explicitly tell it.

The Camel in Action is extremely light on details for interacting with the
cxf component, I wonder if anyone here has any practical advice on how to
set up routes where the operations are all from the same wsdl file? For
example I've had to make the same web service available on multiple ports
(declared multiple cxf:beans) just so that I could associate unique routes
to each operation, which doesn't feel like the right solution.



--
View this message in context: http://camel.465427.n5.nabble.com/Chaining-web-service-calls-in-a-route-tp5786218p5786244.html
Sent from the Camel - Users mailing list archive at Nabble.com.