how to access a SOAP message part inside a route

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

how to access a SOAP message part inside a route

suralk
Hi All,
I have a route that gets some data from a remote we service and writes to a file:
 from("file:src/data?noop=true")
 .to("cxf://http://www.webservicex.net/stockquote.asmx?wsdlURL=src/main/resources/META-INF/stockquote.wsdl&serviceName={http://www.webserviceX.NET/}StockQuote&portName={http://www.webserviceX.NET/}StockQuoteSoap&dataFormat=MESSAGE")        
 .to("file:src/dataout?fileName=t.xml");

This works fine, but I want to access only some of the elements in this SOAP message. I tried a processor like the one shown below, but it is returning null. Can someone point out what is wrong in this route?
I am assuming that I should not cast the SoapBody to Cxfpayload because the dataformat at the endpoint is MESSAGE. However, I do not know an alternative.

.process(new Processor() {
                    @SuppressWarnings("unchecked")
                    public void process(final Exchange exchange) throws Exception {
                        CxfPayload<SoapBody> requestPayload = exchange.getIn().getBody(CxfPayload.class);
                        List<Source> inElements = requestPayload.getBodySources();
                        List<Source> outElements = new ArrayList<Source>();                      
                        for(Source element:inElements)
                        {
                        Element in = new XmlConverter().toDOMElement(element);
                        System.out.println("++++++++++++++" + in.getNodeValue());// prints null
                        }
                       
                    }
                })
Reply | Threaded
Open this post in threaded view
|

Re: how to access a SOAP message part inside a route

Christian Mueller
Administrator
Would XPath or XQuery work for you? Something like

<from uri="xxx"/>
<setHeader headerName="myHeader">
  <xpath>/ns:order/ns:id/text()</xpath>
</setHeader>
<to uri="xxx"/>

[1] http://camel.apache.org/xpath.html
[2] http://camel.apache.org/xquery.html

Best,
Christian

On Tue, Oct 2, 2012 at 7:51 AM, suralk <[hidden email]> wrote:

> Hi All,
> I have a route that gets some data from a remote we service and writes to a
> file:
>  from("file:src/data?noop=true")
>
> .to("cxf://
> http://www.webservicex.net/stockquote.asmx?wsdlURL=src/main/resources/META-INF/stockquote.wsdl&serviceName={http://www.webserviceX.NET/}StockQuote&portName={http://www.webserviceX.NET/}StockQuoteSoap&dataFormat=MESSAGE
> ")
>  .to("file:src/dataout?fileName=t.xml");
>
> This works fine, but I want to access only some of the elements in this
> SOAP
> message. I tried a processor like the one shown below, but it is returning
> null. Can someone point out what is wrong in this route?
> I am assuming that I should not cast the SoapBody to Cxfpayload because the
> dataformat at the endpoint is MESSAGE. However, I do not know an
> alternative.
>
> .process(new Processor() {
>                     @SuppressWarnings("unchecked")
>                     public void process(final Exchange exchange) throws
> Exception {
>                         CxfPayload<SoapBody> requestPayload =
> exchange.getIn().getBody(CxfPayload.class);
>                         List<Source> inElements =
> requestPayload.getBodySources();
>                         List<Source> outElements = new ArrayList<Source>();
>                         for(Source element:inElements)
>                         {
>                                 Element in = new
> XmlConverter().toDOMElement(element);
>                                 System.out.println("++++++++++++++" +
> in.getNodeValue());// prints null
>                         }
>
>                     }
>                 })
>
>
>
> --
> View this message in context:
> http://camel.465427.n5.nabble.com/how-to-access-a-SOAP-message-part-inside-a-route-tp5720345.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
>



--
Reply | Threaded
Open this post in threaded view
|

Re: how to access a SOAP message part inside a route

suralk
Hi Christian,
Sorry I just saw your response.
before that, I sent the below reply to another thread asked by another member regarding the same problem.
I am pasting it here again:

I am using the Camel CXF component with the MESSAGE dataFormat (using
PAYLOAD throws an exception, so have to stick with MESSAGE format with
respect to this particular web service).

I do not want to set any header based on the
extracted soap element. Rather, I want to extract out these soap elements
and use them for some other processing work. However, as I understand, XPath
or XQuery do not support this. They can only be used to set headers, or as
filter conditions.
In this context, what options do we have to extract out elements in the soap
response in MESSAGE mode?
I currently convert the response explicitly to an xml file, but this is not
very elegant.
Reply | Threaded
Open this post in threaded view
|

Re: how to access a SOAP message part inside a route

Raul Kripalani
What would you like to do with the result of the extraction?

Sent from a mobile device
On 2 Oct 2012 22:51, "suralk" <[hidden email]> wrote:

> Hi Christian,
> Sorry I just saw your response.
> before that, I sent the below reply to another thread asked by another
> member regarding the same problem.
> I am pasting it here again:
>
> I am using the Camel CXF component with the MESSAGE dataFormat (using
> PAYLOAD throws an exception, so have to stick with MESSAGE format with
> respect to this particular web service).
>
> I do not want to set any header based on the
> extracted soap element. Rather, I want to extract out these soap elements
> and use them for some other processing work. However, as I understand,
> XPath
> or XQuery do not support this. They can only be used to set headers, or as
> filter conditions.
> In this context, what options do we have to extract out elements in the
> soap
> response in MESSAGE mode?
> I currently convert the response explicitly to an xml file, but this is not
> very elegant.
>
>
>
> --
> View this message in context:
> http://camel.465427.n5.nabble.com/how-to-access-a-SOAP-message-part-inside-a-route-tp5720345p5720402.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
>
Reply | Threaded
Open this post in threaded view
|

Re: how to access a SOAP message part inside a route

suralk
Hi Raul,
I want to extract only a particular element from the soap message and send it to another endpoint. This element value will be stored in the body of the message to the destination endpoint. So I do not want to set it as a header.
i assume that I can assign the element value to a temporary header, and later get it to the body. But this does not look like the correct way to do it. Ideally, I would like to set the body of the message straightaway from the soap element

/sura
Reply | Threaded
Open this post in threaded view
|

Re: how to access a SOAP message part inside a route

Raul Kripalani
Yes, you described just the idea I was about the propose ;) Take into
account that Exchange properties are treated like local variables inside
the route's execution, kind of like BPEL variables if you're familiar with
them. So the way you propose is totally legal.

However, here's an alternative idea. After you get the response from the
endpoint, you can perform a <wireTap /> to a seda: endpoint. This will
create a copy of the Exchange and will branch off and run independently
from the main route. Create a route that consumes from this seda: endpoint,
overrides the body with the value of the XPath (use the <transform /> DSL)
and sends it to the required endpoint.

If, on the other hand, you want the callout to execute synchronously (so
that the main route waits), you can use <enrich /> together with
the UseOriginalAggregationStrategy [1] aggregation strategy. That will
preserve the original Exchange after the callout finishes.

To be fair, doing a synchronous callout with a different payload while
preserving the original Exchange is a typical use case. Maybe we should
support a <callOut /> DSL, which acts like I described above with the
enrich DSL?

[1]
http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/processor/aggregate/UseOriginalAggregationStrategy.html
.

Hope that helps,

--
*Raúl Kripalani*
Apache Camel Committer
Enterprise Architect, Program Manager, Open Source Integration specialist
http://about.me/raulkripalani | http://www.linkedin.com/in/raulkripalani
http://blog.raulkr.net | twitter: @raulvk <http://twitter.com/raulvk>

On Tue, Oct 2, 2012 at 11:04 PM, suralk <[hidden email]> wrote:

> Hi Raul,
> I want to extract only a particular element from the soap message and send
> it to another endpoint. This element value will be stored in the body of
> the
> message to the destination endpoint. So I do not want to set it as a
> header.
> i assume that I can assign the element value to a temporary header, and
> later get it to the body. But this does not look like the correct way to do
> it. Ideally, I would like to set the body of the message straightaway from
> the soap element
>
> /sura
>
>
>
> --
> View this message in context:
> http://camel.465427.n5.nabble.com/how-to-access-a-SOAP-message-part-inside-a-route-tp5720345p5720404.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
>
Reply | Threaded
Open this post in threaded view
|

Re: how to access a SOAP message part inside a route

suralk
Hi Raul,
Thanks a lot.
How about the option of delegating this work to a bean? (like what you have recently proposed in another thread).
Can you please point me to an example of using a bean for such work to access raw soap message.
Reply | Threaded
Open this post in threaded view
|

Re: how to access a SOAP message part inside a route

Raul Kripalani
Sura,

It's really very simple. You can do:

from("jms:queue:myqueue")
   .to("cxf:bean:webservice)            // let's call the response message A
   .log("Received message: ${body}")    // this will print A
   .wireTap("seda:calloutToAnotherEndpoint")    // a copy of A is sent
   .to("file:hello");                   // this continues being A

from("seda:calloutToAnotherEndpoint")       // this is a copy of A
    .transform(xpath("/pick/the/element"))  // replaces the copy of A with
the result of the expression, let's call it B
    .to("jms:queue:anotherQueue");          // B is sent to the callout
endpoint, and B is discarded

I hope that helps.

Thanks,
Raúl.

On Tue, Oct 2, 2012 at 11:26 PM, suralk <[hidden email]> wrote:

> Hi Raul,
> Thanks a lot.
> How about the option of delegating this work to a bean? (like what you have
> recently proposed in another thread).
> Can you please point me to an example of using a bean for such work to
> access raw soap message.
>
>
>
> --
> View this message in context:
> http://camel.465427.n5.nabble.com/how-to-access-a-SOAP-message-part-inside-a-route-tp5720345p5720407.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
>



--
*Raúl Kripalani*
Apache Camel Committer
Enterprise Architect, Program Manager, Open Source Integration specialist
mobile: +34 679 52 41 75
http://about.me/raulkripalani | http://www.linkedin.com/in/raulkripalani
http://blog.raulkr.net | twitter: @raulvk <http://twitter.com/raulvk>