You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by Jason Chaffee <jc...@shopzilla.com> on 2012/12/04 04:00:12 UTC

Setting Header as Xpath expression

Currently, I am using Xpath to read some elements from the body that are integers.  Later in the process, I need to use those integers in a scripting language to do some comparisons and arithmetic.  The problem I am seeing is that when I set the header it is a NodeList object instead of the integer or string from the XML, this causes the logic in the javascript to fail.  I was able to work around the issue, but accessing the NodeList in a Processor and converting it and saving it back in the header.  However, this seems very clunky and an extra step that I would expect to have to do.

Code example is below, is there a better or cleaner way?

    val ns: Namespaces = new Namespaces("soapenv", "http://schemas.xmlsoap.org/soap/envelope/")
    ns.add("ns1", "https://foobar.com/item/v2")


    from("seda:Soap")
      .routeId("Soap")
      .setHeader("SOAPAction", constant("\"getItems\""))
      .to("cxf://" + savingsUri.toString())
      .unmarshal().string("UTF-8")
      .setHeader("hasMore", ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/ns1:hasMore/text()"))
      .setHeader("recordsReturned", ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/ns1:recordsReturned/text()"))
      .setHeader("totalRecordsAvailable", ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/ns1:totalRecordsAvailable/text()"))
      .process(new Processor {
        override def process(exchange: Exchange) {
          val message: Message = exchange.getIn()

          val hasMore: NodeList = message.getHeader("hasMore", classOf[NodeList])
          message.setHeader("hasMore", hasMore.item(0).getTextContent())

          val recordsReturned: NodeList = message.getHeader("recordsReturned", classOf[NodeList])
          message.setHeader("recordsReturned", recordsReturned.item(0).getTextContent())

          val totalRecordsAvailable: NodeList = message.getHeader("totalRecordsAvailable", classOf[NodeList])
          message.setHeader("totalRecordsAvailable", totalRecordsAvailable.item(0).getTextContent())
        }
      })
      .choice()
        .when().javaScript("parseInt(request.headers.get('totalRecordsAvailable')) > parseInt(request.headers.get('StartIndex'))")
          .setHeader("StartIndex").javaScript("(parseInt(request.headers.get('SavingsStartIndex')) + parseInt(request.headers.get('SavingsPageSize'))).toFixed()")
          .choice()
            .when().javaScript("parseInt(request.headers.get('totalRecordsAvailable')) - parseInt(request.headers.get('StartIndex')) < parseInt(request.headers.get('PageSize'))")
              .setHeader("PageSize").javaScript("(parseInt(request.headers.get('totalRecordsAvailable')) - parseInt(request.headers.get('StartIndex'))).toFixed()")
          .endChoice()
          .wireTap("seda:CreateMessage")
      .endChoice()
      .split()
        .tokenizeXML("ns1:items")
        .parallelProcessing()
        .streaming()
      .to("jms:queue:Split")


Re: Setting Header as Xpath expression

Posted by Jason Chaffee <jc...@shopzilla.com>.
Tried that, but for some reason it fails to give me the expected results
as it stops processing after 18,000 records whereas my "hack" finishes
correctly after 34254 records.



On 12/3/12 11:23 PM, "Christian Müller" <ch...@gmail.com>
wrote:

>Indeed, this is clunky... ;-)
>You should be able to do
>ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/ns1:
>totalRecordsAvailable",
>Integer.class)
>or
>ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/ns1:
>totalRecordsAvailable/text()",
>Integer.class)
>
>Doesn't it work for you?
>
>Best,
>Christian
>
>On Tue, Dec 4, 2012 at 4:00 AM, Jason Chaffee
><jc...@shopzilla.com>wrote:
>
>> Currently, I am using Xpath to read some elements from the body that are
>> integers.  Later in the process, I need to use those integers in a
>> scripting language to do some comparisons and arithmetic.  The problem
>>I am
>> seeing is that when I set the header it is a NodeList object instead of
>>the
>> integer or string from the XML, this causes the logic in the javascript
>>to
>> fail.  I was able to work around the issue, but accessing the NodeList
>>in a
>> Processor and converting it and saving it back in the header.  However,
>> this seems very clunky and an extra step that I would expect to have to
>>do.
>>
>> Code example is below, is there a better or cleaner way?
>>
>>     val ns: Namespaces = new Namespaces("soapenv", "
>> http://schemas.xmlsoap.org/soap/envelope/")
>>     ns.add("ns1", "https://foobar.com/item/v2")
>>
>>
>>     from("seda:Soap")
>>       .routeId("Soap")
>>       .setHeader("SOAPAction", constant("\"getItems\""))
>>       .to("cxf://" + savingsUri.toString())
>>       .unmarshal().string("UTF-8")
>>       .setHeader("hasMore",
>> 
>>ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/ns1
>>:hasMore/text()"))
>>       .setHeader("recordsReturned",
>> 
>>ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/ns1
>>:recordsReturned/text()"))
>>       .setHeader("totalRecordsAvailable",
>> 
>>ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/ns1
>>:totalRecordsAvailable/text()"))
>>       .process(new Processor {
>>         override def process(exchange: Exchange) {
>>           val message: Message = exchange.getIn()
>>
>>           val hasMore: NodeList = message.getHeader("hasMore",
>> classOf[NodeList])
>>           message.setHeader("hasMore", hasMore.item(0).getTextContent())
>>
>>           val recordsReturned: NodeList =
>> message.getHeader("recordsReturned", classOf[NodeList])
>>           message.setHeader("recordsReturned",
>> recordsReturned.item(0).getTextContent())
>>
>>           val totalRecordsAvailable: NodeList =
>> message.getHeader("totalRecordsAvailable", classOf[NodeList])
>>           message.setHeader("totalRecordsAvailable",
>> totalRecordsAvailable.item(0).getTextContent())
>>         }
>>       })
>>       .choice()
>>
>> 
>>.when().javaScript("parseInt(request.headers.get('totalRecordsAvailable')
>>)
>> > parseInt(request.headers.get('StartIndex'))")
>>
>> 
>>.setHeader("StartIndex").javaScript("(parseInt(request.headers.get('Savin
>>gsStartIndex'))
>> + parseInt(request.headers.get('SavingsPageSize'))).toFixed()")
>>           .choice()
>>
>> 
>>.when().javaScript("parseInt(request.headers.get('totalRecordsAvailable')
>>)
>> - parseInt(request.headers.get('StartIndex')) <
>> parseInt(request.headers.get('PageSize'))")
>>
>> 
>>.setHeader("PageSize").javaScript("(parseInt(request.headers.get('totalRe
>>cordsAvailable'))
>> - parseInt(request.headers.get('StartIndex'))).toFixed()")
>>           .endChoice()
>>           .wireTap("seda:CreateMessage")
>>       .endChoice()
>>       .split()
>>         .tokenizeXML("ns1:items")
>>         .parallelProcessing()
>>         .streaming()
>>       .to("jms:queue:Split")
>>
>>
>
>
>--


Re: Setting Header as Xpath expression

Posted by Christian Müller <ch...@gmail.com>.
Indeed, this is clunky... ;-)
You should be able to do
ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/ns1:totalRecordsAvailable",
Integer.class)
or
ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/ns1:totalRecordsAvailable/text()",
Integer.class)

Doesn't it work for you?

Best,
Christian

On Tue, Dec 4, 2012 at 4:00 AM, Jason Chaffee <jc...@shopzilla.com>wrote:

> Currently, I am using Xpath to read some elements from the body that are
> integers.  Later in the process, I need to use those integers in a
> scripting language to do some comparisons and arithmetic.  The problem I am
> seeing is that when I set the header it is a NodeList object instead of the
> integer or string from the XML, this causes the logic in the javascript to
> fail.  I was able to work around the issue, but accessing the NodeList in a
> Processor and converting it and saving it back in the header.  However,
> this seems very clunky and an extra step that I would expect to have to do.
>
> Code example is below, is there a better or cleaner way?
>
>     val ns: Namespaces = new Namespaces("soapenv", "
> http://schemas.xmlsoap.org/soap/envelope/")
>     ns.add("ns1", "https://foobar.com/item/v2")
>
>
>     from("seda:Soap")
>       .routeId("Soap")
>       .setHeader("SOAPAction", constant("\"getItems\""))
>       .to("cxf://" + savingsUri.toString())
>       .unmarshal().string("UTF-8")
>       .setHeader("hasMore",
> ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/ns1:hasMore/text()"))
>       .setHeader("recordsReturned",
> ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/ns1:recordsReturned/text()"))
>       .setHeader("totalRecordsAvailable",
> ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/ns1:totalRecordsAvailable/text()"))
>       .process(new Processor {
>         override def process(exchange: Exchange) {
>           val message: Message = exchange.getIn()
>
>           val hasMore: NodeList = message.getHeader("hasMore",
> classOf[NodeList])
>           message.setHeader("hasMore", hasMore.item(0).getTextContent())
>
>           val recordsReturned: NodeList =
> message.getHeader("recordsReturned", classOf[NodeList])
>           message.setHeader("recordsReturned",
> recordsReturned.item(0).getTextContent())
>
>           val totalRecordsAvailable: NodeList =
> message.getHeader("totalRecordsAvailable", classOf[NodeList])
>           message.setHeader("totalRecordsAvailable",
> totalRecordsAvailable.item(0).getTextContent())
>         }
>       })
>       .choice()
>
> .when().javaScript("parseInt(request.headers.get('totalRecordsAvailable'))
> > parseInt(request.headers.get('StartIndex'))")
>
> .setHeader("StartIndex").javaScript("(parseInt(request.headers.get('SavingsStartIndex'))
> + parseInt(request.headers.get('SavingsPageSize'))).toFixed()")
>           .choice()
>
> .when().javaScript("parseInt(request.headers.get('totalRecordsAvailable'))
> - parseInt(request.headers.get('StartIndex')) <
> parseInt(request.headers.get('PageSize'))")
>
> .setHeader("PageSize").javaScript("(parseInt(request.headers.get('totalRecordsAvailable'))
> - parseInt(request.headers.get('StartIndex'))).toFixed()")
>           .endChoice()
>           .wireTap("seda:CreateMessage")
>       .endChoice()
>       .split()
>         .tokenizeXML("ns1:items")
>         .parallelProcessing()
>         .streaming()
>       .to("jms:queue:Split")
>
>


--

Re: Setting Header as Xpath expression

Posted by Jason Chaffee <jc...@shopzilla.com>.
I will debug some more and respond later in the day.  It doesn't aways
fail with an exception.  Often, it just stops processing more messages and
I think that is because the javascript expression is failing to return
true.  The javascript expression is what is setting the headers for
correct pagination of the data as the producer won't allow us to grab all
in one shot.



On 12/4/12 8:45 AM, "Christian Müller" <ch...@gmail.com> wrote:

>Which exception did you get? Can you share the stack trace?
>Which Camel version do you use?
>
>Best,
>Christian
>
>Sent from a mobile device
>Am 04.12.2012 11:40 schrieb "Jason Chaffee" <jc...@shopzilla.com>:
>
>> I take that back.  It worked one time, but not the next time.  However,
>>my
>> hack works with every run.
>>
>>
>>
>> On 12/4/12 1:50 AM, "Jason Chaffee" <jc...@shopzilla.com> wrote:
>>
>> >If I use String.class instead of Integer.class it works.  It could be
>>an
>> >issue with my javascript why the Integer.class didn¹t work.
>> >
>> >
>> >
>> >On 12/4/12 1:20 AM, "Jason Chaffee" <jc...@shopzilla.com> wrote:
>> >
>> >>Tried that, but for some reason it fails to give me the expected
>>results
>> >>as it stops processing after 18,000 records whereas my "hack" finishes
>> >>correctly after 34254 records.
>> >>
>> >>
>> >>
>> >>On 12/3/12 11:19 PM, "Willem jiang" <wi...@gmail.com> wrote:
>> >>
>> >>>Hi,
>> >>>
>> >>>You should be able to set the xpath expression result like this
>> >>>.setHeader("hasMore",
>> 
>>>>>ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/
>>>>>ns
>> >>>1
>> >>>:
>> >>>hasMore/text()", Integer.class))
>> >>>
>> >>>The you don't need to header in you processor.
>> >>>
>> >>>--
>> >>>Willem Jiang
>> >>>
>> >>>Red Hat, Inc.
>> >>>FuseSource is now part of Red Hat
>> >>>Web: http://www.fusesource.com | http://www.redhat.com
>> >>>Blog: http://willemjiang.blogspot.com
>>(http://willemjiang.blogspot.com/
>> )
>> >>>(English)
>> >>>          http://jnn.javaeye.com (http://jnn.javaeye.com/) (Chinese)
>> >>>Twitter: willemjiang
>> >>>Weibo: willemjiang
>> >>>
>> >>>
>> >>>
>> >>>
>> >>>
>> >>>On Tuesday, December 4, 2012 at 11:00 AM, Jason Chaffee wrote:
>> >>>
>> >>>> Currently, I am using Xpath to read some elements from the body
>>that
>> >>>>are integers. Later in the process, I need to use those integers in
>>a
>> >>>>scripting language to do some comparisons and arithmetic. The
>>problem I
>> >>>>am seeing is that when I set the header it is a NodeList object
>>instead
>> >>>>of the integer or string from the XML, this causes the logic in the
>> >>>>javascript to fail. I was able to work around the issue, but
>>accessing
>> >>>>the NodeList in a Processor and converting it and saving it back in
>>the
>> >>>>header. However, this seems very clunky and an extra step that I
>>would
>> >>>>expect to have to do.
>> >>>>
>> >>>> Code example is below, is there a better or cleaner way?
>> >>>>
>> >>>> val ns: Namespaces = new Namespaces("soapenv",
>> >>>>"http://schemas.xmlsoap.org/soap/envelope/")
>> >>>> ns.add("ns1", "https://foobar.com/item/v2")
>> >>>>
>> >>>>
>> >>>> from("seda:Soap")
>> >>>> .routeId("Soap")
>> >>>> .setHeader("SOAPAction", constant("\"getItems\""))
>> >>>> .to("cxf://" + savingsUri.toString())
>> >>>> .unmarshal().string("UTF-8")
>> >>>> .setHeader("hasMore",
>> 
>>>>>>ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out
>>>>>>/n
>> >>>>s
>> >>>>1
>> >>>>:hasMore/text()"))
>> >>>> .setHeader("recordsReturned",
>> 
>>>>>>ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out
>>>>>>/n
>> >>>>s
>> >>>>1
>> >>>>:recordsReturned/text()"))
>> >>>> .setHeader("totalRecordsAvailable",
>> 
>>>>>>ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out
>>>>>>/n
>> >>>>s
>> >>>>1
>> >>>>:totalRecordsAvailable/text()"))
>> >>>> .process(new Processor {
>> >>>> override def process(exchange: Exchange) {
>> >>>> val message: Message = exchange.getIn()
>> >>>>
>> >>>> val hasMore: NodeList = message.getHeader("hasMore",
>> >>>>classOf[NodeList])
>> >>>> message.setHeader("hasMore", hasMore.item(0).getTextContent())
>> >>>>
>> >>>> val recordsReturned: NodeList =
>>message.getHeader("recordsReturned",
>> >>>>classOf[NodeList])
>> >>>> message.setHeader("recordsReturned",
>> >>>>recordsReturned.item(0).getTextContent())
>> >>>>
>> >>>> val totalRecordsAvailable: NodeList =
>> >>>>message.getHeader("totalRecordsAvailable", classOf[NodeList])
>> >>>> message.setHeader("totalRecordsAvailable",
>> >>>>totalRecordsAvailable.item(0).getTextContent())
>> >>>> }
>> >>>> })
>> >>>> .choice()
>> >>>>
>> 
>>>>>>.when().javaScript("parseInt(request.headers.get('totalRecordsAvailab
>>>>>>le
>> >>>>'
>> >>>>)
>> >>>>) > parseInt(request.headers.get('StartIndex'))")
>> >>>>
>> 
>>>>>>.setHeader("StartIndex").javaScript("(parseInt(request.headers.get('S
>>>>>>av
>> >>>>i
>> >>>>n
>> >>>>gsStartIndex')) +
>> >>>>parseInt(request.headers.get('SavingsPageSize'))).toFixed()")
>> >>>> .choice()
>> >>>>
>> 
>>>>>>.when().javaScript("parseInt(request.headers.get('totalRecordsAvailab
>>>>>>le
>> >>>>'
>> >>>>)
>> >>>>) - parseInt(request.headers.get('StartIndex')) <
>> >>>>parseInt(request.headers.get('PageSize'))")
>> >>>>
>> 
>>>>>>.setHeader("PageSize").javaScript("(parseInt(request.headers.get('tot
>>>>>>al
>> >>>>R
>> >>>>e
>> >>>>cordsAvailable')) -
>> >>>>parseInt(request.headers.get('StartIndex'))).toFixed()")
>> >>>> .endChoice()
>> >>>> .wireTap("seda:CreateMessage")
>> >>>> .endChoice()
>> >>>> .split()
>> >>>> .tokenizeXML("ns1:items")
>> >>>> .parallelProcessing()
>> >>>> .streaming()
>> >>>> .to("jms:queue:Split")
>> >>>
>> >>>
>> >>>
>> >>>
>> >>
>> >>
>> >
>> >
>>
>>


Re: Setting Header as Xpath expression

Posted by Christian Müller <ch...@gmail.com>.
Which exception did you get? Can you share the stack trace?
Which Camel version do you use?

Best,
Christian

Sent from a mobile device
Am 04.12.2012 11:40 schrieb "Jason Chaffee" <jc...@shopzilla.com>:

> I take that back.  It worked one time, but not the next time.  However, my
> hack works with every run.
>
>
>
> On 12/4/12 1:50 AM, "Jason Chaffee" <jc...@shopzilla.com> wrote:
>
> >If I use String.class instead of Integer.class it works.  It could be an
> >issue with my javascript why the Integer.class didn¹t work.
> >
> >
> >
> >On 12/4/12 1:20 AM, "Jason Chaffee" <jc...@shopzilla.com> wrote:
> >
> >>Tried that, but for some reason it fails to give me the expected results
> >>as it stops processing after 18,000 records whereas my "hack" finishes
> >>correctly after 34254 records.
> >>
> >>
> >>
> >>On 12/3/12 11:19 PM, "Willem jiang" <wi...@gmail.com> wrote:
> >>
> >>>Hi,
> >>>
> >>>You should be able to set the xpath expression result like this
> >>>.setHeader("hasMore",
> >>>ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/ns
> >>>1
> >>>:
> >>>hasMore/text()", Integer.class))
> >>>
> >>>The you don't need to header in you processor.
> >>>
> >>>--
> >>>Willem Jiang
> >>>
> >>>Red Hat, Inc.
> >>>FuseSource is now part of Red Hat
> >>>Web: http://www.fusesource.com | http://www.redhat.com
> >>>Blog: http://willemjiang.blogspot.com (http://willemjiang.blogspot.com/
> )
> >>>(English)
> >>>          http://jnn.javaeye.com (http://jnn.javaeye.com/) (Chinese)
> >>>Twitter: willemjiang
> >>>Weibo: willemjiang
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>On Tuesday, December 4, 2012 at 11:00 AM, Jason Chaffee wrote:
> >>>
> >>>> Currently, I am using Xpath to read some elements from the body that
> >>>>are integers. Later in the process, I need to use those integers in a
> >>>>scripting language to do some comparisons and arithmetic. The problem I
> >>>>am seeing is that when I set the header it is a NodeList object instead
> >>>>of the integer or string from the XML, this causes the logic in the
> >>>>javascript to fail. I was able to work around the issue, but accessing
> >>>>the NodeList in a Processor and converting it and saving it back in the
> >>>>header. However, this seems very clunky and an extra step that I would
> >>>>expect to have to do.
> >>>>
> >>>> Code example is below, is there a better or cleaner way?
> >>>>
> >>>> val ns: Namespaces = new Namespaces("soapenv",
> >>>>"http://schemas.xmlsoap.org/soap/envelope/")
> >>>> ns.add("ns1", "https://foobar.com/item/v2")
> >>>>
> >>>>
> >>>> from("seda:Soap")
> >>>> .routeId("Soap")
> >>>> .setHeader("SOAPAction", constant("\"getItems\""))
> >>>> .to("cxf://" + savingsUri.toString())
> >>>> .unmarshal().string("UTF-8")
> >>>> .setHeader("hasMore",
> >>>>ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/n
> >>>>s
> >>>>1
> >>>>:hasMore/text()"))
> >>>> .setHeader("recordsReturned",
> >>>>ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/n
> >>>>s
> >>>>1
> >>>>:recordsReturned/text()"))
> >>>> .setHeader("totalRecordsAvailable",
> >>>>ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/n
> >>>>s
> >>>>1
> >>>>:totalRecordsAvailable/text()"))
> >>>> .process(new Processor {
> >>>> override def process(exchange: Exchange) {
> >>>> val message: Message = exchange.getIn()
> >>>>
> >>>> val hasMore: NodeList = message.getHeader("hasMore",
> >>>>classOf[NodeList])
> >>>> message.setHeader("hasMore", hasMore.item(0).getTextContent())
> >>>>
> >>>> val recordsReturned: NodeList = message.getHeader("recordsReturned",
> >>>>classOf[NodeList])
> >>>> message.setHeader("recordsReturned",
> >>>>recordsReturned.item(0).getTextContent())
> >>>>
> >>>> val totalRecordsAvailable: NodeList =
> >>>>message.getHeader("totalRecordsAvailable", classOf[NodeList])
> >>>> message.setHeader("totalRecordsAvailable",
> >>>>totalRecordsAvailable.item(0).getTextContent())
> >>>> }
> >>>> })
> >>>> .choice()
> >>>>
> >>>>.when().javaScript("parseInt(request.headers.get('totalRecordsAvailable
> >>>>'
> >>>>)
> >>>>) > parseInt(request.headers.get('StartIndex'))")
> >>>>
> >>>>.setHeader("StartIndex").javaScript("(parseInt(request.headers.get('Sav
> >>>>i
> >>>>n
> >>>>gsStartIndex')) +
> >>>>parseInt(request.headers.get('SavingsPageSize'))).toFixed()")
> >>>> .choice()
> >>>>
> >>>>.when().javaScript("parseInt(request.headers.get('totalRecordsAvailable
> >>>>'
> >>>>)
> >>>>) - parseInt(request.headers.get('StartIndex')) <
> >>>>parseInt(request.headers.get('PageSize'))")
> >>>>
> >>>>.setHeader("PageSize").javaScript("(parseInt(request.headers.get('total
> >>>>R
> >>>>e
> >>>>cordsAvailable')) -
> >>>>parseInt(request.headers.get('StartIndex'))).toFixed()")
> >>>> .endChoice()
> >>>> .wireTap("seda:CreateMessage")
> >>>> .endChoice()
> >>>> .split()
> >>>> .tokenizeXML("ns1:items")
> >>>> .parallelProcessing()
> >>>> .streaming()
> >>>> .to("jms:queue:Split")
> >>>
> >>>
> >>>
> >>>
> >>
> >>
> >
> >
>
>

Re: Setting Header as Xpath expression

Posted by Jason Chaffee <jc...@shopzilla.com>.
I take that back.  It worked one time, but not the next time.  However, my
hack works with every run.



On 12/4/12 1:50 AM, "Jason Chaffee" <jc...@shopzilla.com> wrote:

>If I use String.class instead of Integer.class it works.  It could be an
>issue with my javascript why the Integer.class didn¹t work.
>
>
>
>On 12/4/12 1:20 AM, "Jason Chaffee" <jc...@shopzilla.com> wrote:
>
>>Tried that, but for some reason it fails to give me the expected results
>>as it stops processing after 18,000 records whereas my "hack" finishes
>>correctly after 34254 records.
>>
>>
>>
>>On 12/3/12 11:19 PM, "Willem jiang" <wi...@gmail.com> wrote:
>>
>>>Hi,
>>>
>>>You should be able to set the xpath expression result like this
>>>.setHeader("hasMore",
>>>ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/ns
>>>1
>>>:
>>>hasMore/text()", Integer.class))
>>>
>>>The you don't need to header in you processor.
>>>
>>>-- 
>>>Willem Jiang
>>>
>>>Red Hat, Inc.
>>>FuseSource is now part of Red Hat
>>>Web: http://www.fusesource.com | http://www.redhat.com
>>>Blog: http://willemjiang.blogspot.com (http://willemjiang.blogspot.com/)
>>>(English)
>>>          http://jnn.javaeye.com (http://jnn.javaeye.com/) (Chinese)
>>>Twitter: willemjiang
>>>Weibo: willemjiang
>>>
>>>
>>>
>>>
>>>
>>>On Tuesday, December 4, 2012 at 11:00 AM, Jason Chaffee wrote:
>>>
>>>> Currently, I am using Xpath to read some elements from the body that
>>>>are integers. Later in the process, I need to use those integers in a
>>>>scripting language to do some comparisons and arithmetic. The problem I
>>>>am seeing is that when I set the header it is a NodeList object instead
>>>>of the integer or string from the XML, this causes the logic in the
>>>>javascript to fail. I was able to work around the issue, but accessing
>>>>the NodeList in a Processor and converting it and saving it back in the
>>>>header. However, this seems very clunky and an extra step that I would
>>>>expect to have to do.
>>>> 
>>>> Code example is below, is there a better or cleaner way?
>>>> 
>>>> val ns: Namespaces = new Namespaces("soapenv",
>>>>"http://schemas.xmlsoap.org/soap/envelope/")
>>>> ns.add("ns1", "https://foobar.com/item/v2")
>>>> 
>>>> 
>>>> from("seda:Soap")
>>>> .routeId("Soap")
>>>> .setHeader("SOAPAction", constant("\"getItems\""))
>>>> .to("cxf://" + savingsUri.toString())
>>>> .unmarshal().string("UTF-8")
>>>> .setHeader("hasMore",
>>>>ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/n
>>>>s
>>>>1
>>>>:hasMore/text()"))
>>>> .setHeader("recordsReturned",
>>>>ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/n
>>>>s
>>>>1
>>>>:recordsReturned/text()"))
>>>> .setHeader("totalRecordsAvailable",
>>>>ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/n
>>>>s
>>>>1
>>>>:totalRecordsAvailable/text()"))
>>>> .process(new Processor {
>>>> override def process(exchange: Exchange) {
>>>> val message: Message = exchange.getIn()
>>>> 
>>>> val hasMore: NodeList = message.getHeader("hasMore",
>>>>classOf[NodeList])
>>>> message.setHeader("hasMore", hasMore.item(0).getTextContent())
>>>> 
>>>> val recordsReturned: NodeList = message.getHeader("recordsReturned",
>>>>classOf[NodeList])
>>>> message.setHeader("recordsReturned",
>>>>recordsReturned.item(0).getTextContent())
>>>> 
>>>> val totalRecordsAvailable: NodeList =
>>>>message.getHeader("totalRecordsAvailable", classOf[NodeList])
>>>> message.setHeader("totalRecordsAvailable",
>>>>totalRecordsAvailable.item(0).getTextContent())
>>>> }
>>>> })
>>>> .choice()
>>>> 
>>>>.when().javaScript("parseInt(request.headers.get('totalRecordsAvailable
>>>>'
>>>>)
>>>>) > parseInt(request.headers.get('StartIndex'))")
>>>> 
>>>>.setHeader("StartIndex").javaScript("(parseInt(request.headers.get('Sav
>>>>i
>>>>n
>>>>gsStartIndex')) +
>>>>parseInt(request.headers.get('SavingsPageSize'))).toFixed()")
>>>> .choice()
>>>> 
>>>>.when().javaScript("parseInt(request.headers.get('totalRecordsAvailable
>>>>'
>>>>)
>>>>) - parseInt(request.headers.get('StartIndex')) <
>>>>parseInt(request.headers.get('PageSize'))")
>>>> 
>>>>.setHeader("PageSize").javaScript("(parseInt(request.headers.get('total
>>>>R
>>>>e
>>>>cordsAvailable')) -
>>>>parseInt(request.headers.get('StartIndex'))).toFixed()")
>>>> .endChoice()
>>>> .wireTap("seda:CreateMessage")
>>>> .endChoice()
>>>> .split()
>>>> .tokenizeXML("ns1:items")
>>>> .parallelProcessing()
>>>> .streaming()
>>>> .to("jms:queue:Split")
>>>
>>>
>>>
>>>
>>
>>
>
>


Re: Setting Header as Xpath expression

Posted by Jason Chaffee <jc...@shopzilla.com>.
If I use String.class instead of Integer.class it works.  It could be an
issue with my javascript why the Integer.class didn¹t work.



On 12/4/12 1:20 AM, "Jason Chaffee" <jc...@shopzilla.com> wrote:

>Tried that, but for some reason it fails to give me the expected results
>as it stops processing after 18,000 records whereas my "hack" finishes
>correctly after 34254 records.
>
>
>
>On 12/3/12 11:19 PM, "Willem jiang" <wi...@gmail.com> wrote:
>
>>Hi,
>>
>>You should be able to set the xpath expression result like this
>>.setHeader("hasMore",
>>ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/ns1
>>:
>>hasMore/text()", Integer.class))
>>
>>The you don't need to header in you processor.
>>
>>-- 
>>Willem Jiang
>>
>>Red Hat, Inc.
>>FuseSource is now part of Red Hat
>>Web: http://www.fusesource.com | http://www.redhat.com
>>Blog: http://willemjiang.blogspot.com (http://willemjiang.blogspot.com/)
>>(English)
>>          http://jnn.javaeye.com (http://jnn.javaeye.com/) (Chinese)
>>Twitter: willemjiang
>>Weibo: willemjiang
>>
>>
>>
>>
>>
>>On Tuesday, December 4, 2012 at 11:00 AM, Jason Chaffee wrote:
>>
>>> Currently, I am using Xpath to read some elements from the body that
>>>are integers. Later in the process, I need to use those integers in a
>>>scripting language to do some comparisons and arithmetic. The problem I
>>>am seeing is that when I set the header it is a NodeList object instead
>>>of the integer or string from the XML, this causes the logic in the
>>>javascript to fail. I was able to work around the issue, but accessing
>>>the NodeList in a Processor and converting it and saving it back in the
>>>header. However, this seems very clunky and an extra step that I would
>>>expect to have to do.
>>> 
>>> Code example is below, is there a better or cleaner way?
>>> 
>>> val ns: Namespaces = new Namespaces("soapenv",
>>>"http://schemas.xmlsoap.org/soap/envelope/")
>>> ns.add("ns1", "https://foobar.com/item/v2")
>>> 
>>> 
>>> from("seda:Soap")
>>> .routeId("Soap")
>>> .setHeader("SOAPAction", constant("\"getItems\""))
>>> .to("cxf://" + savingsUri.toString())
>>> .unmarshal().string("UTF-8")
>>> .setHeader("hasMore",
>>>ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/ns
>>>1
>>>:hasMore/text()"))
>>> .setHeader("recordsReturned",
>>>ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/ns
>>>1
>>>:recordsReturned/text()"))
>>> .setHeader("totalRecordsAvailable",
>>>ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/ns
>>>1
>>>:totalRecordsAvailable/text()"))
>>> .process(new Processor {
>>> override def process(exchange: Exchange) {
>>> val message: Message = exchange.getIn()
>>> 
>>> val hasMore: NodeList = message.getHeader("hasMore", classOf[NodeList])
>>> message.setHeader("hasMore", hasMore.item(0).getTextContent())
>>> 
>>> val recordsReturned: NodeList = message.getHeader("recordsReturned",
>>>classOf[NodeList])
>>> message.setHeader("recordsReturned",
>>>recordsReturned.item(0).getTextContent())
>>> 
>>> val totalRecordsAvailable: NodeList =
>>>message.getHeader("totalRecordsAvailable", classOf[NodeList])
>>> message.setHeader("totalRecordsAvailable",
>>>totalRecordsAvailable.item(0).getTextContent())
>>> }
>>> })
>>> .choice()
>>> 
>>>.when().javaScript("parseInt(request.headers.get('totalRecordsAvailable'
>>>)
>>>) > parseInt(request.headers.get('StartIndex'))")
>>> 
>>>.setHeader("StartIndex").javaScript("(parseInt(request.headers.get('Savi
>>>n
>>>gsStartIndex')) +
>>>parseInt(request.headers.get('SavingsPageSize'))).toFixed()")
>>> .choice()
>>> 
>>>.when().javaScript("parseInt(request.headers.get('totalRecordsAvailable'
>>>)
>>>) - parseInt(request.headers.get('StartIndex')) <
>>>parseInt(request.headers.get('PageSize'))")
>>> 
>>>.setHeader("PageSize").javaScript("(parseInt(request.headers.get('totalR
>>>e
>>>cordsAvailable')) -
>>>parseInt(request.headers.get('StartIndex'))).toFixed()")
>>> .endChoice()
>>> .wireTap("seda:CreateMessage")
>>> .endChoice()
>>> .split()
>>> .tokenizeXML("ns1:items")
>>> .parallelProcessing()
>>> .streaming()
>>> .to("jms:queue:Split")
>>
>>
>>
>>
>
>


Re: Setting Header as Xpath expression

Posted by Jason Chaffee <jc...@shopzilla.com>.
Tried that, but for some reason it fails to give me the expected results
as it stops processing after 18,000 records whereas my "hack" finishes
correctly after 34254 records.



On 12/3/12 11:19 PM, "Willem jiang" <wi...@gmail.com> wrote:

>Hi,
>
>You should be able to set the xpath expression result like this
>.setHeader("hasMore",
>ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/ns1:
>hasMore/text()", Integer.class))
>
>The you don't need to header in you processor.
>
>-- 
>Willem Jiang
>
>Red Hat, Inc.
>FuseSource is now part of Red Hat
>Web: http://www.fusesource.com | http://www.redhat.com
>Blog: http://willemjiang.blogspot.com (http://willemjiang.blogspot.com/)
>(English)
>          http://jnn.javaeye.com (http://jnn.javaeye.com/) (Chinese)
>Twitter: willemjiang
>Weibo: willemjiang
>
>
>
>
>
>On Tuesday, December 4, 2012 at 11:00 AM, Jason Chaffee wrote:
>
>> Currently, I am using Xpath to read some elements from the body that
>>are integers. Later in the process, I need to use those integers in a
>>scripting language to do some comparisons and arithmetic. The problem I
>>am seeing is that when I set the header it is a NodeList object instead
>>of the integer or string from the XML, this causes the logic in the
>>javascript to fail. I was able to work around the issue, but accessing
>>the NodeList in a Processor and converting it and saving it back in the
>>header. However, this seems very clunky and an extra step that I would
>>expect to have to do.
>> 
>> Code example is below, is there a better or cleaner way?
>> 
>> val ns: Namespaces = new Namespaces("soapenv",
>>"http://schemas.xmlsoap.org/soap/envelope/")
>> ns.add("ns1", "https://foobar.com/item/v2")
>> 
>> 
>> from("seda:Soap")
>> .routeId("Soap")
>> .setHeader("SOAPAction", constant("\"getItems\""))
>> .to("cxf://" + savingsUri.toString())
>> .unmarshal().string("UTF-8")
>> .setHeader("hasMore",
>>ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/ns1
>>:hasMore/text()"))
>> .setHeader("recordsReturned",
>>ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/ns1
>>:recordsReturned/text()"))
>> .setHeader("totalRecordsAvailable",
>>ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/ns1
>>:totalRecordsAvailable/text()"))
>> .process(new Processor {
>> override def process(exchange: Exchange) {
>> val message: Message = exchange.getIn()
>> 
>> val hasMore: NodeList = message.getHeader("hasMore", classOf[NodeList])
>> message.setHeader("hasMore", hasMore.item(0).getTextContent())
>> 
>> val recordsReturned: NodeList = message.getHeader("recordsReturned",
>>classOf[NodeList])
>> message.setHeader("recordsReturned",
>>recordsReturned.item(0).getTextContent())
>> 
>> val totalRecordsAvailable: NodeList =
>>message.getHeader("totalRecordsAvailable", classOf[NodeList])
>> message.setHeader("totalRecordsAvailable",
>>totalRecordsAvailable.item(0).getTextContent())
>> }
>> })
>> .choice()
>> 
>>.when().javaScript("parseInt(request.headers.get('totalRecordsAvailable')
>>) > parseInt(request.headers.get('StartIndex'))")
>> 
>>.setHeader("StartIndex").javaScript("(parseInt(request.headers.get('Savin
>>gsStartIndex')) +
>>parseInt(request.headers.get('SavingsPageSize'))).toFixed()")
>> .choice()
>> 
>>.when().javaScript("parseInt(request.headers.get('totalRecordsAvailable')
>>) - parseInt(request.headers.get('StartIndex')) <
>>parseInt(request.headers.get('PageSize'))")
>> 
>>.setHeader("PageSize").javaScript("(parseInt(request.headers.get('totalRe
>>cordsAvailable')) -
>>parseInt(request.headers.get('StartIndex'))).toFixed()")
>> .endChoice()
>> .wireTap("seda:CreateMessage")
>> .endChoice()
>> .split()
>> .tokenizeXML("ns1:items")
>> .parallelProcessing()
>> .streaming()
>> .to("jms:queue:Split")
>
>
>
>


Re: Setting Header as Xpath expression

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

You should be able to set the xpath expression result like this
.setHeader("hasMore", ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/ns1:hasMore/text()", Integer.class))

The you don't need to header in you processor. 

-- 
Willem Jiang

Red Hat, Inc.
FuseSource is now part of Red Hat
Web: http://www.fusesource.com | http://www.redhat.com
Blog: http://willemjiang.blogspot.com (http://willemjiang.blogspot.com/) (English)
          http://jnn.javaeye.com (http://jnn.javaeye.com/) (Chinese)
Twitter: willemjiang 
Weibo: willemjiang





On Tuesday, December 4, 2012 at 11:00 AM, Jason Chaffee wrote:

> Currently, I am using Xpath to read some elements from the body that are integers. Later in the process, I need to use those integers in a scripting language to do some comparisons and arithmetic. The problem I am seeing is that when I set the header it is a NodeList object instead of the integer or string from the XML, this causes the logic in the javascript to fail. I was able to work around the issue, but accessing the NodeList in a Processor and converting it and saving it back in the header. However, this seems very clunky and an extra step that I would expect to have to do.
> 
> Code example is below, is there a better or cleaner way?
> 
> val ns: Namespaces = new Namespaces("soapenv", "http://schemas.xmlsoap.org/soap/envelope/")
> ns.add("ns1", "https://foobar.com/item/v2")
> 
> 
> from("seda:Soap")
> .routeId("Soap")
> .setHeader("SOAPAction", constant("\"getItems\""))
> .to("cxf://" + savingsUri.toString())
> .unmarshal().string("UTF-8")
> .setHeader("hasMore", ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/ns1:hasMore/text()"))
> .setHeader("recordsReturned", ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/ns1:recordsReturned/text()"))
> .setHeader("totalRecordsAvailable", ns.xpath("/soapenv:Envelope/soapenv:Body/ns1:getItemsResponse/ns1:out/ns1:totalRecordsAvailable/text()"))
> .process(new Processor {
> override def process(exchange: Exchange) {
> val message: Message = exchange.getIn()
> 
> val hasMore: NodeList = message.getHeader("hasMore", classOf[NodeList])
> message.setHeader("hasMore", hasMore.item(0).getTextContent())
> 
> val recordsReturned: NodeList = message.getHeader("recordsReturned", classOf[NodeList])
> message.setHeader("recordsReturned", recordsReturned.item(0).getTextContent())
> 
> val totalRecordsAvailable: NodeList = message.getHeader("totalRecordsAvailable", classOf[NodeList])
> message.setHeader("totalRecordsAvailable", totalRecordsAvailable.item(0).getTextContent())
> }
> })
> .choice()
> .when().javaScript("parseInt(request.headers.get('totalRecordsAvailable')) > parseInt(request.headers.get('StartIndex'))")
> .setHeader("StartIndex").javaScript("(parseInt(request.headers.get('SavingsStartIndex')) + parseInt(request.headers.get('SavingsPageSize'))).toFixed()")
> .choice()
> .when().javaScript("parseInt(request.headers.get('totalRecordsAvailable')) - parseInt(request.headers.get('StartIndex')) < parseInt(request.headers.get('PageSize'))")
> .setHeader("PageSize").javaScript("(parseInt(request.headers.get('totalRecordsAvailable')) - parseInt(request.headers.get('StartIndex'))).toFixed()")
> .endChoice()
> .wireTap("seda:CreateMessage")
> .endChoice()
> .split()
> .tokenizeXML("ns1:items")
> .parallelProcessing()
> .streaming()
> .to("jms:queue:Split")