beginner question

View: New views
7 Messages — Rating Filter:   Alert me  

beginner question

by Paul Phillips :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi there

bit of a beginner question here.

I have a situation where I want to

- get some xml from a jms queue
- send an id contained in the xml to a custom component i have written (the body of the request should be a string that looks like this: "ID=blah", so I use a bean to grab the id using xpath and change the body of the exchange)
- this will return a message with a body that looks like "MATCHED=TRUE" or something
- if MATCHED=TRUE then I want to send some xml to a different endpoint.

However this final xml will be using stuff from the original xml that has been "discarded" on the way (? I am not even sure about this)

What is the best way to go about getting this "old" data?

hope it makes sense. I'm probably missing something really simple I know.

A snippet from my route at the moment looks roughly like this:

from("direct:deleteRoute").bean(Normalise.class, "getID").enrich("ioe:test:test1").choice().when(body().contains("MATCHED=TRUE").to("ioe:test3");

where ioe uri's refer to my own custom component

Hope all this makes sense!

Thanks
Paul.


Re: beginner question

by James.Strachan :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

2009/10/23 Paul Phillips <djphillyp@...>:

>
> Hi there
>
> bit of a beginner question here.
>
> I have a situation where I want to
>
> - get some xml from a jms queue
> - send an id contained in the xml to a custom component i have written (the
> body of the request should be a string that looks like this: "ID=blah", so I
> use a bean to grab the id using xpath and change the body of the exchange)
> - this will return a message with a body that looks like "MATCHED=TRUE" or
> something
> - if MATCHED=TRUE then I want to send some xml to a different endpoint.

BTW you can do the above like this...

public class MyBean {

  @Consume(uri="activemq:SomeQueue")
  pubilc void onXml(@XPath("/foo/ID") String myID, Document restOfBody) {
    // return the transformed payload
    return "MATCHED=TRUE"
  }
}

Notice Camel can do the XPath for you and inject the ID parameter to
your transformer method (myID) - also notice the lack of any
middleware APIs etc.

for more details see
http://camel.apache.org/pojo-consuming.html

--
James
-------
http://macstrac.blogspot.com/

Open Source Integration
http://fusesource.com/

Re: beginner question

by Claus Ibsen-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Fri, Oct 23, 2009 at 6:35 PM, Paul Phillips <djphillyp@...> wrote:

>
> Hi there
>
> bit of a beginner question here.
>
> I have a situation where I want to
>
> - get some xml from a jms queue
> - send an id contained in the xml to a custom component i have written (the
> body of the request should be a string that looks like this: "ID=blah", so I
> use a bean to grab the id using xpath and change the body of the exchange)
> - this will return a message with a body that looks like "MATCHED=TRUE" or
> something
> - if MATCHED=TRUE then I want to send some xml to a different endpoint.
>
> However this final xml will be using stuff from the original xml that has
> been "discarded" on the way (? I am not even sure about this)
>
> What is the best way to go about getting this "old" data?
>
> hope it makes sense. I'm probably missing something really simple I know.
>
> A snippet from my route at the moment looks roughly like this:
>
> from("direct:deleteRoute").bean(Normalise.class,
> "getID").enrich("ioe:test:test1").choice().when(body().contains("MATCHED=TRUE").to("ioe:test3");
>
> where ioe uri's refer to my own custom component
>
> Hope all this makes sense!
>

Yeah the route example helps :)

Your custom component could store the answer as a header then you can
keep the original message along the way.

However you can also in fact the the original input message from the Camel API
   Message original = exchange.getUnitOfWork().getOriginalMessage();
   Object body = original.getBody();

But other people just store the payload as an Exchange property then
they can always grab it back later on demand

.setProperty("foo", body())
.// do something else
// and now restore the body back
.setBody(property("foo"))





> Thanks
> Paul.
>
>
> --
> View this message in context: http://www.nabble.com/beginner-question-tp26029591p26029591.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
>
>



--
Claus Ibsen
Apache Camel Committer

Author of Camel in Action: http://www.manning.com/ibsen/
Open Source Integration: http://fusesource.com
Blog: http://davsclaus.blogspot.com/
Twitter: http://twitter.com/davsclaus

Re: beginner question

by Paul Phillips :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Ok great.

From this I've now realised that what I really want to do is grab a bunch of stuff from the incoming xml and store it as properties on the message for future use in the route and then I don't really need the original xml anymore.

Now I could write some code like this:

DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
    domFactory.setNamespaceAware(true); // never forget this!
    DocumentBuilder builder = domFactory.newDocumentBuilder();
    Document doc = builder.parse(theIncomingXML);

    XPathFactory factory = XPathFactory.newInstance();
    XPath xpath = factory.newXPath();
    XPathExpression expr
     = xpath.compile("//book[author='Neal Stephenson']/title/text()");

    Object result = expr.evaluate(doc, XPathConstants.NODESET);
 
and store the result objects as properties on the message.

Is there an "easier" way to do this with Camel? If I am in a class that implements Processor, in the process method, can I access the xpath "helper" stuff that camel provides so that I can just (almost) say

String interestingText = message.xpath("//book[author='Neal Stephenson']/title/text()")

and it'll handle the parsing etc for me?





James.Strachan wrote:
2009/10/23 Paul Phillips <djphillyp@gmail.com>:
>
> Hi there
>
> bit of a beginner question here.
>
> I have a situation where I want to
>
> - get some xml from a jms queue
> - send an id contained in the xml to a custom component i have written (the
> body of the request should be a string that looks like this: "ID=blah", so I
> use a bean to grab the id using xpath and change the body of the exchange)
> - this will return a message with a body that looks like "MATCHED=TRUE" or
> something
> - if MATCHED=TRUE then I want to send some xml to a different endpoint.

BTW you can do the above like this...

public class MyBean {

  @Consume(uri="activemq:SomeQueue")
  pubilc void onXml(@XPath("/foo/ID") String myID, Document restOfBody) {
    // return the transformed payload
    return "MATCHED=TRUE"
  }
}

Notice Camel can do the XPath for you and inject the ID parameter to
your transformer method (myID) - also notice the lack of any
middleware APIs etc.

for more details see
http://camel.apache.org/pojo-consuming.html

--
James
-------
http://macstrac.blogspot.com/

Open Source Integration
http://fusesource.com/

Re: beginner question

by Claus Ibsen-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, Oct 28, 2009 at 2:58 PM, Paul Phillips <djphillyp@...> wrote:

>
> Ok great.
>
> From this I've now realised that what I really want to do is grab a bunch of
> stuff from the incoming xml and store it as properties on the message for
> future use in the route and then I don't really need the original xml
> anymore.
>
> Now I could write some code like this:
>
> DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
>    domFactory.setNamespaceAware(true); // never forget this!
>    DocumentBuilder builder = domFactory.newDocumentBuilder();
>    Document doc = builder.parse(theIncomingXML);
>
>    XPathFactory factory = XPathFactory.newInstance();
>    XPath xpath = factory.newXPath();
>    XPathExpression expr
>     = xpath.compile("//book[author='Neal Stephenson']/title/text()");
>
>    Object result = expr.evaluate(doc, XPathConstants.NODESET);
>
> and store the result objects as properties on the message.
>
> Is there an "easier" way to do this with Camel? If I am in a class that
> implements Processor, in the process method, can I access the xpath "helper"
> stuff that camel provides so that I can just (almost) say
>
> String interestingText = message.xpath("//book[author='Neal
> Stephenson']/title/text()")
>
> and it'll handle the parsing etc for me?

Yeah as you work in a Processor where you have the Exchange object handy

Something like this. You may need to tweak it a bit.

String interestingText = xpath("//book[author='Neal
Stephenson']/title/text()").evaluate(exchange, String.class);



>
>
>
>
>
>
> James.Strachan wrote:
>>
>> 2009/10/23 Paul Phillips <djphillyp@...>:
>>>
>>> Hi there
>>>
>>> bit of a beginner question here.
>>>
>>> I have a situation where I want to
>>>
>>> - get some xml from a jms queue
>>> - send an id contained in the xml to a custom component i have written
>>> (the
>>> body of the request should be a string that looks like this: "ID=blah",
>>> so I
>>> use a bean to grab the id using xpath and change the body of the
>>> exchange)
>>> - this will return a message with a body that looks like "MATCHED=TRUE"
>>> or
>>> something
>>> - if MATCHED=TRUE then I want to send some xml to a different endpoint.
>>
>> BTW you can do the above like this...
>>
>> public class MyBean {
>>
>>   @Consume(uri="activemq:SomeQueue")
>>   pubilc void onXml(@XPath("/foo/ID") String myID, Document restOfBody) {
>>     // return the transformed payload
>>     return "MATCHED=TRUE"
>>   }
>> }
>>
>> Notice Camel can do the XPath for you and inject the ID parameter to
>> your transformer method (myID) - also notice the lack of any
>> middleware APIs etc.
>>
>> for more details see
>> http://camel.apache.org/pojo-consuming.html
>>
>> --
>> James
>> -------
>> http://macstrac.blogspot.com/
>>
>> Open Source Integration
>> http://fusesource.com/
>>
>>
>
> --
> View this message in context: http://www.nabble.com/beginner-question-tp26029591p26095101.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
>
>



--
Claus Ibsen
Apache Camel Committer

Author of Camel in Action: http://www.manning.com/ibsen/
Open Source Integration: http://fusesource.com
Blog: http://davsclaus.blogspot.com/
Twitter: http://twitter.com/davsclaus

Re: beginner question

by Paul Phillips :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

That pointed me in the right direction. Here's a working line of code:

String interestingText = new XPathExpression("//book[author='Neal Stephenson']/title/text()").evaluate(exchange, String.class);

XPathExpression was the class I couldn't find :)

Thanks!


Claus Ibsen-2 wrote:
On Wed, Oct 28, 2009 at 2:58 PM, Paul Phillips <djphillyp@gmail.com> wrote:
>
> Ok great.
>
> From this I've now realised that what I really want to do is grab a bunch of
> stuff from the incoming xml and store it as properties on the message for
> future use in the route and then I don't really need the original xml
> anymore.
>
> Now I could write some code like this:
>
> DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
>    domFactory.setNamespaceAware(true); // never forget this!
>    DocumentBuilder builder = domFactory.newDocumentBuilder();
>    Document doc = builder.parse(theIncomingXML);
>
>    XPathFactory factory = XPathFactory.newInstance();
>    XPath xpath = factory.newXPath();
>    XPathExpression expr
>     = xpath.compile("//book[author='Neal Stephenson']/title/text()");
>
>    Object result = expr.evaluate(doc, XPathConstants.NODESET);
>
> and store the result objects as properties on the message.
>
> Is there an "easier" way to do this with Camel? If I am in a class that
> implements Processor, in the process method, can I access the xpath "helper"
> stuff that camel provides so that I can just (almost) say
>
> String interestingText = message.xpath("//book[author='Neal
> Stephenson']/title/text()")
>
> and it'll handle the parsing etc for me?

Yeah as you work in a Processor where you have the Exchange object handy

Something like this. You may need to tweak it a bit.

String interestingText = xpath("//book[author='Neal
Stephenson']/title/text()").evaluate(exchange, String.class);



>
>
>
>
>
>
> James.Strachan wrote:
>>
>> 2009/10/23 Paul Phillips <djphillyp@gmail.com>:
>>>
>>> Hi there
>>>
>>> bit of a beginner question here.
>>>
>>> I have a situation where I want to
>>>
>>> - get some xml from a jms queue
>>> - send an id contained in the xml to a custom component i have written
>>> (the
>>> body of the request should be a string that looks like this: "ID=blah",
>>> so I
>>> use a bean to grab the id using xpath and change the body of the
>>> exchange)
>>> - this will return a message with a body that looks like "MATCHED=TRUE"
>>> or
>>> something
>>> - if MATCHED=TRUE then I want to send some xml to a different endpoint.
>>
>> BTW you can do the above like this...
>>
>> public class MyBean {
>>
>>   @Consume(uri="activemq:SomeQueue")
>>   pubilc void onXml(@XPath("/foo/ID") String myID, Document restOfBody) {
>>     // return the transformed payload
>>     return "MATCHED=TRUE"
>>   }
>> }
>>
>> Notice Camel can do the XPath for you and inject the ID parameter to
>> your transformer method (myID) - also notice the lack of any
>> middleware APIs etc.
>>
>> for more details see
>> http://camel.apache.org/pojo-consuming.html
>>
>> --
>> James
>> -------
>> http://macstrac.blogspot.com/
>>
>> Open Source Integration
>> http://fusesource.com/
>>
>>
>
> --
> View this message in context: http://www.nabble.com/beginner-question-tp26029591p26095101.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
>
>



--
Claus Ibsen
Apache Camel Committer

Author of Camel in Action: http://www.manning.com/ibsen/
Open Source Integration: http://fusesource.com
Blog: http://davsclaus.blogspot.com/
Twitter: http://twitter.com/davsclaus

Re: beginner question

by Claus Ibsen-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, Oct 28, 2009 at 3:29 PM, Paul Phillips <djphillyp@...> wrote:
>
> That pointed me in the right direction. Here's a working line of code:
>
> String interestingText = new XPathExpression("//book[author='Neal
> Stephenson']/title/text()").evaluate(exchange, String.class);
>
> XPathExpression was the class I couldn't find :)
>

Cool. I am frankly surprised there isnt any easy to use library that
can make the bloddy SUN API a breeze to use.
Nobody wants to write 10 lines of xpath factory etc. code to just grab
a piece from a XML document.

Anyone know of any?


Unfortunately the Camel one is currently a bit to tightly coupled with
Exchange. We may loosen that in the future and let you
evaluate any kind of object so we can provide a nicer helper for you to use.



> Thanks!
>
>
>
> Claus Ibsen-2 wrote:
>>
>> On Wed, Oct 28, 2009 at 2:58 PM, Paul Phillips <djphillyp@...>
>> wrote:
>>>
>>> Ok great.
>>>
>>> From this I've now realised that what I really want to do is grab a bunch
>>> of
>>> stuff from the incoming xml and store it as properties on the message for
>>> future use in the route and then I don't really need the original xml
>>> anymore.
>>>
>>> Now I could write some code like this:
>>>
>>> DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
>>>    domFactory.setNamespaceAware(true); // never forget this!
>>>    DocumentBuilder builder = domFactory.newDocumentBuilder();
>>>    Document doc = builder.parse(theIncomingXML);
>>>
>>>    XPathFactory factory = XPathFactory.newInstance();
>>>    XPath xpath = factory.newXPath();
>>>    XPathExpression expr
>>>     = xpath.compile("//book[author='Neal Stephenson']/title/text()");
>>>
>>>    Object result = expr.evaluate(doc, XPathConstants.NODESET);
>>>
>>> and store the result objects as properties on the message.
>>>
>>> Is there an "easier" way to do this with Camel? If I am in a class that
>>> implements Processor, in the process method, can I access the xpath
>>> "helper"
>>> stuff that camel provides so that I can just (almost) say
>>>
>>> String interestingText = message.xpath("//book[author='Neal
>>> Stephenson']/title/text()")
>>>
>>> and it'll handle the parsing etc for me?
>>
>> Yeah as you work in a Processor where you have the Exchange object handy
>>
>> Something like this. You may need to tweak it a bit.
>>
>> String interestingText = xpath("//book[author='Neal
>> Stephenson']/title/text()").evaluate(exchange, String.class);
>>
>>
>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> James.Strachan wrote:
>>>>
>>>> 2009/10/23 Paul Phillips <djphillyp@...>:
>>>>>
>>>>> Hi there
>>>>>
>>>>> bit of a beginner question here.
>>>>>
>>>>> I have a situation where I want to
>>>>>
>>>>> - get some xml from a jms queue
>>>>> - send an id contained in the xml to a custom component i have written
>>>>> (the
>>>>> body of the request should be a string that looks like this: "ID=blah",
>>>>> so I
>>>>> use a bean to grab the id using xpath and change the body of the
>>>>> exchange)
>>>>> - this will return a message with a body that looks like "MATCHED=TRUE"
>>>>> or
>>>>> something
>>>>> - if MATCHED=TRUE then I want to send some xml to a different endpoint.
>>>>
>>>> BTW you can do the above like this...
>>>>
>>>> public class MyBean {
>>>>
>>>>   @Consume(uri="activemq:SomeQueue")
>>>>   pubilc void onXml(@XPath("/foo/ID") String myID, Document restOfBody)
>>>> {
>>>>     // return the transformed payload
>>>>     return "MATCHED=TRUE"
>>>>   }
>>>> }
>>>>
>>>> Notice Camel can do the XPath for you and inject the ID parameter to
>>>> your transformer method (myID) - also notice the lack of any
>>>> middleware APIs etc.
>>>>
>>>> for more details see
>>>> http://camel.apache.org/pojo-consuming.html
>>>>
>>>> --
>>>> James
>>>> -------
>>>> http://macstrac.blogspot.com/
>>>>
>>>> Open Source Integration
>>>> http://fusesource.com/
>>>>
>>>>
>>>
>>> --
>>> View this message in context:
>>> http://www.nabble.com/beginner-question-tp26029591p26095101.html
>>> Sent from the Camel - Users mailing list archive at Nabble.com.
>>>
>>>
>>
>>
>>
>> --
>> Claus Ibsen
>> Apache Camel Committer
>>
>> Author of Camel in Action: http://www.manning.com/ibsen/
>> Open Source Integration: http://fusesource.com
>> Blog: http://davsclaus.blogspot.com/
>> Twitter: http://twitter.com/davsclaus
>>
>>
>
> --
> View this message in context: http://www.nabble.com/beginner-question-tp26029591p26095588.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
>
>



--
Claus Ibsen
Apache Camel Committer

Author of Camel in Action: http://www.manning.com/ibsen/
Open Source Integration: http://fusesource.com
Blog: http://davsclaus.blogspot.com/
Twitter: http://twitter.com/davsclaus