You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by William Tam <em...@gmail.com> on 2010/12/07 16:18:26 UTC

Re: cxf:consumer and cxf:producer in one route

Mixing of POJO and PAYLOAD is probably fine but you have to do some 
conversion (e.g. in a processor).  You know the message body for POJO 
mode is List<Object> and for PAYLOAD mode is CxfPayload.   So, it needs 
conversion from a List<Object> to CxfPayload for the request and convert 
back from CxfPayload to List<Object> on the response.

from(cxf://...?dataFormat=POJO).process(convertRequest).to(cxf://...?dataFormat=PAYLOAD).process(convertResponse)

As to whether mixing mode is necessary, you might want to consider 
leverage JAXWS handler to access SOAP header and perform any pre/post 
processing.   Here is an example of using JAXWS in Camel.


https://svn.apache.org/repos/asf/camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/wsdl_first/JaxwsTestHandler.java

https://svn.apache.org/repos/asf/camel/trunk/components/camel-cxf/src/test/resources/org/apache/camel/component/cxf/WsdlFirstProcessor.xml

https://svn.apache.org/repos/asf/camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/CxfWsdlFirstProcessorTest.java

HTH


On 12/07/2010 03:35 AM, Thomas KRIECHBAUM wrote:
> Hello,
>
> in my integration prototype an existing web-service should be adapted to
> an other contract. Therefore, I have a cxf:consumer(dataFormat=PAYLOAD;
> the associated cxf:endpoint definition references a WSDL but no service
> class) and a cxf:producer (the associated cxf:endpoint references a
> service class that has been generated from a WSDL). In this scenario, I?m
> getting an exception, when the response is send back within the
> cxf:consumer (XMLStreamDataWriter.write expects DataSource, Node or
> Source) .
> After doing some debugging, binding.populateCxfResponseFromExchange
> extracts the data format from the current exchange (in my case
> cxf:producer with data format POJO) and not the current endpoint (in my
> case cxf:consumer with data format PAYLOAD).
>
> What's the correct interaction between those components? The mix of data
> formats is needed, because
> 1.) the SOAP headers should be inspected
> 2.) the incoming SOAP message can contain invalid type representation
> (e.g. timestamp) that have to be corrected before =>  POJO can not be used
> in this case
>
> code from org.apache.camel.component.cxf.CxfConsumer
>
> @SuppressWarnings("unchecked")
> private void setResponseBack(Exchange cxfExchange,
> org.apache.camel.Exchange camelExchange) {
>      CxfEndpoint endpoint = (CxfEndpoint)getEndpoint();
>      CxfBinding binding = endpoint.getCxfBinding();
>
>      checkFailure(camelExchange);
>
>      // bind the Camel response into a CXF response
>      if (camelExchange.getPattern().isOutCapable()) {
>          binding.populateCxfResponseFromExchange(camelExchange,
> cxfExchange);
>      }
>
>      // check failure again as fault could be discovered by converter
>      checkFailure(camelExchange);
>
>      // copy the headers javax.xml.ws header back
>      binding.copyJaxWsContext(cxfExchange, (Map<String,
> Object>)camelExchange.getProperty(CxfConstants.JAXWS_CONTEXT));
> }
>
> I?m using camel-cxf 2.5.0
>
> Thanks,
> Thomas
>
>
>
> Der Austausch von Nachrichten mit o.a. Absender via e-mail dient ausschließlich Informationszwecken. Rechtsgeschäftliche Erklärungen dürfen über dieses Medium nicht ausgetauscht werden.
>
> Correspondence with a.m. sender via e-mail is only for information purposes. This medium is not to be used for the exchange of legally-binding communications.
>
>    

Antwort: Re: cxf:consumer and cxf:producer in one route

Posted by Thomas KRIECHBAUM <kr...@grz.at>.
Hello,

thanks for your help. The suggested workaround works fine as long as both 
cxf:components are bound to the same WSDL.

What are the recommended steps, if an existing web service should be 
provided by a new contract (WSDL of first cxf:component differs from WSDL 
of second cxf:component).

from(cxf://...?dataFormat=PAYLOAD).process(convertRequest).to(cxf://...?dataFormat=POJO).process(convertResponse)

Beside the already discussed conversions I also had to change the 
following headers for invoking the correct service operation (see 
CxfProducer. getBindingOperationInfo):

exchange.getIn().setHeader(CxfConstants.OPERATION_NAME, ...);
exchange.getIn().setHeader(CxfConstants.OPERATION_NAMESPACE, ...);

This can be seen as typical integration step. But a behind-the-scene 
analysis of the request-object for determining the appropriate web-service 
operation would be nice.

Furthermore, tips and best practices for this integration scenario would 
be a great help (this simple prototype should be used as a reference for 
other projects within our organization).

William Tam <em...@gmail.com> schrieb am 09.12.2010 20:06:39:

> I think you need to set the mode back to PAYLOAD mode inside the second 
> processor (convertResponse) until CAMEL-3420 is fixed and delivered.  I 
> added a unit test for your reference.
> 
> https://svn.apache.org/repos/asf/camel/trunk/components/camel-
> 
cxf/src/test/java/org/apache/camel/component/cxf/CxfMixedModeRouterTest.java
> 
> On 12/09/2010 02:28 AM, Thomas KRIECHBAUM wrote:
> > Hello,
> >
> > the conversion does not help. It seams, that the second cxf-component
> > (POJO) changes the camel exchange in a way the first cxf-component
> > (PAYLOAD) can't deal with. For simplicity, I have bound both 
components to
> > the same WSDL, but even if I wrap the response from the second
> > cxf-component to an CxPayload (body-list contains one DOM-element) it
> > could not be serialized to XML by the XMLStreamDataWriter.
> >
> > Here is my route:
> > from(cxf://...?dataFormat=PAYLOAD).process(convertRequest).to(cxf:
> //...?dataFormat=POJO).process(convertResponse)
> >
> > Do I have to apply some kind of pattern to preserve to information of 
the
> > first cxf-component (headers, CxfConstants.DATA_FORMAT_PROPERTY, ...)
> > before invoking the second cxf-component?
> > Can the second cxf-compoent works on its own camel exchange instance?
> >
> > For testing purposes, if have implemented a processor that creates the
> > CxfPayload without calling the second cxf-component. In this case, the
> > CxfPayload is serialized to XML as expected.
> > The route:
> > from(cxf://...?dataFormat=PAYLOAD).process(createPayload)
> >
> > 
> >> Mixing of POJO and PAYLOAD is probably fine but you have to do some
> >> conversion (e.g. in a processor).  You know the message body for POJO
> >> mode is List<Object>  and for PAYLOAD mode is CxfPayload.   So, it 
needs
> >> conversion from a List<Object>  to CxfPayload for the request and 
convert
> >> 
> > 
> >> back from CxfPayload to List<Object>  on the response.
> >>
> >> from(cxf://...?dataFormat=POJO).process(convertRequest).to(cxf://...?
> >> dataFormat=PAYLOAD).process(convertResponse)
> >> 
> >
> >
> >
> >
> > Der Austausch von Nachrichten mit o.a. Absender via e-mail dient 
> ausschließlich Informationszwecken. Rechtsgeschäftliche Erklärungen 
> dürfen über dieses Medium nicht ausgetauscht werden.
> >
> > Correspondence with a.m. sender via e-mail is only for information 
> purposes. This medium is not to be used for the exchange of legally-
> binding communications.
> >
> > 




Der Austausch von Nachrichten mit o.a. Absender via e-mail dient ausschließlich Informationszwecken. Rechtsgeschäftliche Erklärungen dürfen über dieses Medium nicht ausgetauscht werden.

Correspondence with a.m. sender via e-mail is only for information purposes. This medium is not to be used for the exchange of legally-binding communications.

Re: cxf:consumer and cxf:producer in one route

Posted by William Tam <em...@gmail.com>.
I think you need to set the mode back to PAYLOAD mode inside the second 
processor (convertResponse) until CAMEL-3420 is fixed and delivered.  I 
added a unit test for your reference.

https://svn.apache.org/repos/asf/camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/CxfMixedModeRouterTest.java

On 12/09/2010 02:28 AM, Thomas KRIECHBAUM wrote:
> Hello,
>
> the conversion does not help. It seams, that the second cxf-component
> (POJO) changes the camel exchange in a way the first cxf-component
> (PAYLOAD) can't deal with. For simplicity, I have bound both components to
> the same WSDL, but even if I wrap the response from the second
> cxf-component to an CxPayload (body-list contains one DOM-element) it
> could not be serialized to XML by the XMLStreamDataWriter.
>
> Here is my route:
> from(cxf://...?dataFormat=PAYLOAD).process(convertRequest).to(cxf://...?dataFormat=POJO).process(convertResponse)
>
> Do I have to apply some kind of pattern to preserve to information of the
> first cxf-component (headers, CxfConstants.DATA_FORMAT_PROPERTY, ...)
> before invoking the second cxf-component?
> Can the second cxf-compoent works on its own camel exchange instance?
>
> For testing purposes, if have implemented a processor that creates the
> CxfPayload without calling the second cxf-component. In this case, the
> CxfPayload is serialized to XML as expected.
> The route:
> from(cxf://...?dataFormat=PAYLOAD).process(createPayload)
>
>    
>> Mixing of POJO and PAYLOAD is probably fine but you have to do some
>> conversion (e.g. in a processor).  You know the message body for POJO
>> mode is List<Object>  and for PAYLOAD mode is CxfPayload.   So, it needs
>> conversion from a List<Object>  to CxfPayload for the request and convert
>>      
>    
>> back from CxfPayload to List<Object>  on the response.
>>
>> from(cxf://...?dataFormat=POJO).process(convertRequest).to(cxf://...?
>> dataFormat=PAYLOAD).process(convertResponse)
>>      
>
>
>
>
> Der Austausch von Nachrichten mit o.a. Absender via e-mail dient ausschließlich Informationszwecken. Rechtsgeschäftliche Erklärungen dürfen über dieses Medium nicht ausgetauscht werden.
>
> Correspondence with a.m. sender via e-mail is only for information purposes. This medium is not to be used for the exchange of legally-binding communications.
>
>    

Re: Re: cxf:consumer and cxf:producer in one route

Posted by Thomas KRIECHBAUM <kr...@grz.at>.
Hello,

the conversion does not help. It seams, that the second cxf-component 
(POJO) changes the camel exchange in a way the first cxf-component 
(PAYLOAD) can't deal with. For simplicity, I have bound both components to 
the same WSDL, but even if I wrap the response from the second 
cxf-component to an CxPayload (body-list contains one DOM-element) it 
could not be serialized to XML by the XMLStreamDataWriter.

Here is my route:
from(cxf://...?dataFormat=PAYLOAD).process(convertRequest).to(cxf://...?dataFormat=POJO).process(convertResponse)

Do I have to apply some kind of pattern to preserve to information of the 
first cxf-component (headers, CxfConstants.DATA_FORMAT_PROPERTY, ...) 
before invoking the second cxf-component?
Can the second cxf-compoent works on its own camel exchange instance?

For testing purposes, if have implemented a processor that creates the 
CxfPayload without calling the second cxf-component. In this case, the 
CxfPayload is serialized to XML as expected.
The route:
from(cxf://...?dataFormat=PAYLOAD).process(createPayload)

> Mixing of POJO and PAYLOAD is probably fine but you have to do some 
> conversion (e.g. in a processor).  You know the message body for POJO 
> mode is List<Object> and for PAYLOAD mode is CxfPayload.   So, it needs 
> conversion from a List<Object> to CxfPayload for the request and convert 

> back from CxfPayload to List<Object> on the response.
> 
> from(cxf://...?dataFormat=POJO).process(convertRequest).to(cxf://...?
> dataFormat=PAYLOAD).process(convertResponse)





Der Austausch von Nachrichten mit o.a. Absender via e-mail dient ausschließlich Informationszwecken. Rechtsgeschäftliche Erklärungen dürfen über dieses Medium nicht ausgetauscht werden.

Correspondence with a.m. sender via e-mail is only for information purposes. This medium is not to be used for the exchange of legally-binding communications.