You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by unmarshall <un...@gmail.com> on 2010/11/10 12:05:52 UTC

Camel CXF Producer should allow setting of BindingOperationInfo

Hi All,

If i have a route in which one or more external webservices are called and
then i want to expose this entire route as a service then the recommended
way is to add the starting endpoint as a cxf endpoint.

So the route becomes:

from("cxf:bean:routeEntryEndpoint")
.convertBodyTo(String.class)
.to("xslt:converter1.xslt") //possibly convert the incoming request to
create a request for the external WS
.to("cxf:bean:externalWS1Endoint");

There can be many more endpoints in the route but for brevity i have kept it
short. So everything works fine till the endpoint which represents the
external webservice is reached. This web service has its own set of
operations defined in the separate wsdl. So now when a call goes to this
endpoint then an exception is thrown:

] Exception: java.lang.IllegalArgumentException: BindingOperationInfo must
be specified
14:28:13.461 WARN  [227137515@qtp-915227122-1 -
/cxf/salesOrderDetailsForClaimsProcessing]
o.a.cxf.phase.PhaseInterceptorChain [Slf4jLogger.java:92] - Interceptor for
{http://www.example.com/cmservices}SalesOrderDetailsForClaimProcessingQueryResponse_In_SAService#{http://www.example.com/cmservices}ReadSalesOrderDetailsForClaimProcessing
has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: BindingOperationInfo must be specified
        at
org.apache.camel.component.cxf.CxfConsumer$1.checkFailure(CxfConsumer.java:123)
~[na:na]

To make this work a custom processor had to be included before calling the
external WS endpoint which would explicitly set the Operation Name and
Operation Namespace on the exchange. 

Ideally this should be a property on the endpoint. I tried using the
defaultOperation and defaultOperationNamespace but when i looked at the
CxfProducer code then i found that this would not work as it never tries to
read these properties.

Is there already a way apart from explicitly using a custom processor? If
not then there is a strong case to include that.

Best Regards,
Madhav
-- 
View this message in context: http://camel.465427.n5.nabble.com/Camel-CXF-Producer-should-allow-setting-of-BindingOperationInfo-tp3258474p3258474.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Camel CXF Producer should allow setting of BindingOperationInfo

Posted by hyjshanghai <hy...@gmail.com>.
I think you should set the Header and DefaultOperationName of
exchange.getOut(), not those of exchange.getIn().

--
View this message in context: http://camel.465427.n5.nabble.com/Camel-CXF-Producer-should-allow-setting-of-BindingOperationInfo-tp3258474p3696949.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Camel CXF Producer should allow setting of BindingOperationInfo

Posted by Willem Jiang <wi...@gmail.com>.
It looks you are setting the message header rightly.
Can you send me a test case ? So I can debug the issue with it.

BTW, which version of Camel are you using ?

On 3/15/11 2:42 AM, tjain2011 wrote:
> Hi
> Can you please elaborate on this. I am in the similar situation. How did you
> set the
> operation name and namespace for the next endpoint.
>
> And do i need to create CxfProducer (a client) for the second endpoint which
> will then call the
> external webservice.
> Here is what i am doing ...but i am sure its not right as i get this
> exception of
>
> java.lang.IllegalArgumentException: BindingOperationInfo must be specified
>
> from("cxf:bean:releasePOEndpoint").handleFault()
> 		.to("log:incoming?showAll=true").process(new Processor() {
> 			public void process(Exchange exchange) throws Exception {
> 				logger.info(" cxf:bean:releasePOEndpoint processing exchange in camel");
>
> 				BindingOperationInfo boi = (BindingOperationInfo)
> 				exchange.getProperty(BindingOperationInfo.class.toString());
> 				if (boi != null) {
> 					logger.info("boi.isUnwrapped" + boi.isUnwrapped());
> 				}
> 				if (exchange != null){
> 					Message in = exchange.getIn();
> 					
> 	
> exchange.getIn().setHeader(CxfConstants.OPERATION_NAMESPACE,"http://zappos.com/pehz/wsdl/purchase_order_service.v1_0");
> exchange.getIn().setHeader(CxfConstants.OPERATION_NAME,
> "releasePurchaseOrder");
> 					
> 					exchange.getIn().setBody(in.getBody());
> 				}
> 			}
> 		})
> 		.to("log:incoming?showAll=true")
>
> 	
> .to("cxf:bean:PurchaseOrderLifeEndpoint?defaultOperationName=releasePurchaseOrder&dataFormat=POJO&defaultOperationNameSpace=http://zappos.com/pehz/wsdl/purchase_order_service.v1_0").to("log:incoming?showAll=true")
> 		.to("mock:end");
>
> --
> View this message in context: http://camel.465427.n5.nabble.com/Camel-CXF-Producer-should-allow-setting-of-BindingOperationInfo-tp3258474p3580264.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
>


-- 
Willem
----------------------------------
FuseSource
Web: http://www.fusesource.com
Blog:    http://willemjiang.blogspot.com (English)
          http://jnn.javaeye.com (Chinese)
Twitter: willemjiang

Re: Camel CXF Producer should allow setting of BindingOperationInfo

Posted by tjain2011 <tj...@gmail.com>.
Hi 
Can you please elaborate on this. I am in the similar situation. How did you
set the
operation name and namespace for the next endpoint.

And do i need to create CxfProducer (a client) for the second endpoint which
will then call the
external webservice.
Here is what i am doing ...but i am sure its not right as i get this
exception of

java.lang.IllegalArgumentException: BindingOperationInfo must be specified

from("cxf:bean:releasePOEndpoint").handleFault()
		.to("log:incoming?showAll=true").process(new Processor() {
			public void process(Exchange exchange) throws Exception {
				logger.info(" cxf:bean:releasePOEndpoint processing exchange in camel");

				BindingOperationInfo boi = (BindingOperationInfo) 
				exchange.getProperty(BindingOperationInfo.class.toString());
				if (boi != null) {
					logger.info("boi.isUnwrapped" + boi.isUnwrapped());
				}
				if (exchange != null){
					Message in = exchange.getIn();
					
	    
exchange.getIn().setHeader(CxfConstants.OPERATION_NAMESPACE,"http://zappos.com/pehz/wsdl/purchase_order_service.v1_0");
exchange.getIn().setHeader(CxfConstants.OPERATION_NAME,
"releasePurchaseOrder");
					
					exchange.getIn().setBody(in.getBody());
				}
			}
		})
		.to("log:incoming?showAll=true")

	
.to("cxf:bean:PurchaseOrderLifeEndpoint?defaultOperationName=releasePurchaseOrder&dataFormat=POJO&defaultOperationNameSpace=http://zappos.com/pehz/wsdl/purchase_order_service.v1_0").to("log:incoming?showAll=true")
		.to("mock:end");

--
View this message in context: http://camel.465427.n5.nabble.com/Camel-CXF-Producer-should-allow-setting-of-BindingOperationInfo-tp3258474p3580264.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Camel CXF Producer should allow setting of BindingOperationInfo

Posted by unmarshall <un...@gmail.com>.
Hi Willem,

Thanks for your response. The problem is this:

The start of the route is a CXF endpoint, now this refers to a different
WSDL. The first endpoint is responsible to only accept the request SOAP
request. Now this first (entry of the route) endpoint may or may not process
this request SOAP request.

So for the first endpoint a CxfConsumer is created and for the second
endpoint a CxfProducer is created (a client) which will then call the
external webservice.

Now while creating the CxfConsumer for the first end point the operation
name and namespace is set in the message exchange. So when the same exchange
goes to the second endpoint then the operation name and namespace are
already set with the details of the first endpoint. But the second point
which now calls the external webservice refers to the external webservice
which is different from the first endpoints webservices.

So the check you are talking about never gets executed. The reason being
that the binding operation info which is set in the exchange is for the
previous endpoint. 

To make it work i had to insert a custom processor which will set the
operation name and namespace for the next endpoint. I find this a hack.

I hope you get the problem.

Best Regards,
madhav




Willem.Jiang wrote:
> 
> On 11/10/10 7:05 PM, unmarshall wrote:
>>
>> Hi All,
>>
>> If i have a route in which one or more external webservices are called
>> and
>> then i want to expose this entire route as a service then the recommended
>> way is to add the starting endpoint as a cxf endpoint.
>>
>> So the route becomes:
>>
>> from("cxf:bean:routeEntryEndpoint")
>> .convertBodyTo(String.class)
>> .to("xslt:converter1.xslt") //possibly convert the incoming request to
>> create a request for the external WS
>> .to("cxf:bean:externalWS1Endoint");
>>
>> There can be many more endpoints in the route but for brevity i have kept
>> it
>> short. So everything works fine till the endpoint which represents the
>> external webservice is reached. This web service has its own set of
>> operations defined in the separate wsdl. So now when a call goes to this
>> endpoint then an exception is thrown:
>>
>> ] Exception: java.lang.IllegalArgumentException: BindingOperationInfo
>> must
>> be specified
>> 14:28:13.461 WARN  [227137515@qtp-915227122-1 -
>> /cxf/salesOrderDetailsForClaimsProcessing]
>> o.a.cxf.phase.PhaseInterceptorChain [Slf4jLogger.java:92] - Interceptor
>> for
>> {http://www.example.com/cmservices}SalesOrderDetailsForClaimProcessingQueryResponse_In_SAService#{http://www.example.com/cmservices}ReadSalesOrderDetailsForClaimProcessing
>> has thrown exception, unwinding now
>> org.apache.cxf.interceptor.Fault: BindingOperationInfo must be specified
>>          at
>> org.apache.camel.component.cxf.CxfConsumer$1.checkFailure(CxfConsumer.java:123)
>> ~[na:na]
>>
>> To make this work a custom processor had to be included before calling
>> the
>> external WS endpoint which would explicitly set the Operation Name and
>> Operation Namespace on the exchange.
>>
>> Ideally this should be a property on the endpoint. I tried using the
>> defaultOperation and defaultOperationNamespace but when i looked at the
>> CxfProducer code then i found that this would not work as it never tries
>> to
>> read these properties.
> 
> Which version of Camel are you using?
> I just checked the code of CxfProducer, it will use the 
> defaultOperationName when there is no OperationName set on the header 
> like this.
> 
> BindingOperationInfo answer = null;
>          String lp = ex.getIn().getHeader(CxfConstants.OPERATION_NAME, 
> String.class);
>          if (lp == null) {
>              lp = endpoint.getDefaultOperationName();
>          }
> You may need to filter these header from the message in you custom 
> processor if you want to use the default one.
> 
>>
>> Is there already a way apart from explicitly using a custom processor? If
>> not then there is a strong case to include that.
>>
>> Best Regards,
>> Madhav
> 
> 
> -- 
> Willem
> ----------------------------------
> FuseSource
> Web: http://www.fusesource.com
> Blog:    http://willemjiang.blogspot.com (English)
>           http://jnn.javaeye.com (Chinese)
> Twitter: willemjiang
> 
> 

-- 
View this message in context: http://camel.465427.n5.nabble.com/Camel-CXF-Producer-should-allow-setting-of-BindingOperationInfo-tp3258474p3262646.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Camel CXF Producer should allow setting of BindingOperationInfo

Posted by Willem Jiang <wi...@gmail.com>.
On 11/10/10 7:05 PM, unmarshall wrote:
>
> Hi All,
>
> If i have a route in which one or more external webservices are called and
> then i want to expose this entire route as a service then the recommended
> way is to add the starting endpoint as a cxf endpoint.
>
> So the route becomes:
>
> from("cxf:bean:routeEntryEndpoint")
> .convertBodyTo(String.class)
> .to("xslt:converter1.xslt") //possibly convert the incoming request to
> create a request for the external WS
> .to("cxf:bean:externalWS1Endoint");
>
> There can be many more endpoints in the route but for brevity i have kept it
> short. So everything works fine till the endpoint which represents the
> external webservice is reached. This web service has its own set of
> operations defined in the separate wsdl. So now when a call goes to this
> endpoint then an exception is thrown:
>
> ] Exception: java.lang.IllegalArgumentException: BindingOperationInfo must
> be specified
> 14:28:13.461 WARN  [227137515@qtp-915227122-1 -
> /cxf/salesOrderDetailsForClaimsProcessing]
> o.a.cxf.phase.PhaseInterceptorChain [Slf4jLogger.java:92] - Interceptor for
> {http://www.example.com/cmservices}SalesOrderDetailsForClaimProcessingQueryResponse_In_SAService#{http://www.example.com/cmservices}ReadSalesOrderDetailsForClaimProcessing
> has thrown exception, unwinding now
> org.apache.cxf.interceptor.Fault: BindingOperationInfo must be specified
>          at
> org.apache.camel.component.cxf.CxfConsumer$1.checkFailure(CxfConsumer.java:123)
> ~[na:na]
>
> To make this work a custom processor had to be included before calling the
> external WS endpoint which would explicitly set the Operation Name and
> Operation Namespace on the exchange.
>
> Ideally this should be a property on the endpoint. I tried using the
> defaultOperation and defaultOperationNamespace but when i looked at the
> CxfProducer code then i found that this would not work as it never tries to
> read these properties.

Which version of Camel are you using?
I just checked the code of CxfProducer, it will use the 
defaultOperationName when there is no OperationName set on the header 
like this.

BindingOperationInfo answer = null;
         String lp = ex.getIn().getHeader(CxfConstants.OPERATION_NAME, 
String.class);
         if (lp == null) {
             lp = endpoint.getDefaultOperationName();
         }
You may need to filter these header from the message in you custom 
processor if you want to use the default one.

>
> Is there already a way apart from explicitly using a custom processor? If
> not then there is a strong case to include that.
>
> Best Regards,
> Madhav


-- 
Willem
----------------------------------
FuseSource
Web: http://www.fusesource.com
Blog:    http://willemjiang.blogspot.com (English)
          http://jnn.javaeye.com (Chinese)
Twitter: willemjiang