Hi, Claus.  Thanks for the response.

Actually, I always do the following in my Route.configure():

  getContext().setStreamCaching(true);

(I do it by default now.  I can't even remember when I *wouldn't* want to do 
it...)

Anyway, even with stream caching on, the body is getting nulled out in this 
simple route if I use xpath().

(So that's 2 things that were nulling the body: xpath() and unmarshal().)

At any rate, it works fine using "simple" and doing a string op.

Maybe at some point I'll revisit trying to figure out what's going on with 
xpath()...

Thanks again.

Ron

> On June 25, 2019 at 11:24 PM Claus Ibsen <claus.ib...@gmail.com> wrote:
> 
> 
> Hi
> 
> For null body, see this FAQ
> http://camel.apache.org/why-is-my-message-body-empty.html
> 
> On Tue, Jun 25, 2019 at 10:24 PM Ron Cecchini <roncecch...@comcast.net> wrote:
> >
> >
> > Sweet Baby Jesus, I got it, guys!  Thank you so much.
> >
> > I hadn't used xpath() before, so I started reading and playing with it.
> >
> > The messages I have to parse are pretty simple, with unique root tags: 
> > "StatusMessage" or "DataMessage".
> >
> > So I tried the following and started having success with it:
> >
> >                 .choice()
> >                     .when().xpath("name(/*) = 'StatusMessage'")
> >                         .to("direct:StatusMessage")
> >                     .when().xpath("name(/*) = 'DataMessage'")
> >                         .to("direct:DataMessage")
> >                     .otherwise()
> >                         .log("***** ERROR!  Got an unknown message 
> > type!\n${body}");
> >
> > But then I quickly saw that the body was *again* null when entering the 2 
> > "direct" routes.
> >
> > I decided not to waste too much time trying to figure out the xpath 
> > idiosyncracies and instead thought about our old friend "simple" and 
> > working with the original message as a string (i.e. no unmarshalling).
> >
> > It worked like a charm!
> >
> > Ultimately I went with the following:
> >
> >         from("netty4:udp://[blahblah]")
> >                 .choice()
> >                     .when(simple("${bodyAs(String)} contains 
> > 'StatusMessage'"))
> >                         .to("direct:StatusMessage")
> >                     .when(simple("${bodyAs(String)} contains 
> > 'DataMessage'"))
> >                         .to("direct:DataMessage")
> >                     .otherwise()
> >                         .log("***** ERROR!  Got an unknown message 
> > type!\n${body}");
> >
> >         from("direct:StatusMessage")
> >                 .doTry()
> >                     .unmarshal(statusMessageFormat)
> >                     .process(new StatusMessageProcessor())
> >                 .doCatch(Exception.class)
> >                     .log("*** ERROR: handling Status Message - exception: 
> > ${exception.message}");
> >
> > > On June 25, 2019 at 12:52 PM "Hart, James W." <jwh...@seic.com> wrote:
> > >
> > >
> > > You can unmarshal well formed xml without the type and then use an xpath 
> > > and choice to decide what to do with the different XMLs.  This might mean 
> > > some extra steps, but it should work.  The error handling method could be 
> > > a little messy.
> > >
> > > Another lower level way would be to inspect what's in the body in a 
> > > processor and setting a header or property of the type.  Then you can use 
> > > a choice to basically route to the correct unmarshal code.  You can use 
> > > String find, or regex if you want to do this and keep the body intact, 
> > > then you can unmarshal the way you do below.
> > >
> > >
> > > -----Original Message-----
> > > From: Ron Cecchini [mailto:roncecch...@comcast.net]
> > > Sent: Tuesday, June 25, 2019 12:10 PM
> > > To: users@camel.apache.org
> > > Subject: Re: How to unmarshal when you don't know what you're 
> > > unmarshalling?
> > >
> > > [[ SEI WARNING *** This email was sent from an external source. Do not 
> > > open attachments or click on links from unknown or suspicious senders. 
> > > *** ]]
> > >
> > >
> > > Unfortunately, I can't.
> > >
> > > The device I'm listening to sends a mix of "Status" and "Data" messages 
> > > over the same UDP port.
> > >
> > > I've been trying to implement the strategy I alluded to, using 
> > > doTry/doCatch to try unmarshalling as one message type, and then the 
> > > other ... but things have gotten gnarly:
> > >
> > > I first solved the problem having to do with the Camel Java DSL not 
> > > handling nested doTry blocks very well.  (I broke up the route, used some 
> > > "direct" routes, etc.)
> > >
> > > Ok, fine.
> > >
> > > The problem I've been banging my head on *now*, though, is the fact that 
> > > it *seems* that trying to do the first unmarshal() blows away any 
> > > properties I set on the exchange!  What the heck...
> > >
> > > In other words:
> > >
> > > When I first get something off the wire (the message over UDP), I save a 
> > > copy of the body:
> > >
> > >         .setProperty("bodyCopy", body())
> > >
> > > Here's the first bit of processing.  I've added a bunch of logging.
> > > In the log statement immediately before the unmarshal, the 'bodyCopy' is 
> > > there.
> > > Immediately after the unmarshal, it's gone.
> > >
> > >         .doTry()
> > >             .log("doTry: BEFORE unmarshal - bodyCopy: 
> > > ${property[bodyCopy]}")
> > >             .unmarshal(dataMessageFormat)
> > >             .log("doTry: BEFORE process - bodyCopy: 
> > > ${property[bodyCopy]}")
> > >             .process(new DataMessageProcessor())
> > >         .doCatch(Exception.class)
> > >             .log("*** ERROR: couldn't unmarshal or process Data Message; 
> > > will try as Status Message")
> > >             .log("about to setBody - bodyCopy: ${property[bodyCopy]}")
> > >             .setBody(exchangeProperty("bodyCopy"))
> > >             .to("direct:tryStatusMessage")
> > >
> > > I found only one other person reporting something similar, back in 
> > > October 2018:
> > >
> > > http://camel.465427.n5.nabble.com/Apache-Camel-JAXB-unmarshalling-returns-null-properties-after-upgrade-from-Camel-from-2-20-4-to-2-211-tt5824549.html
> > >
> > > The recommendation was to downgrade the version of 'jaxb-impl' being used 
> > > -- which I'm not using.
> > >
> > > FWIW, I created this project from the Camel Spring Boot archetype, which 
> > > is setting the Camel version at 2.21.1.  I'm using 'camel-jaxb-starter' 
> > > for my JAXB, and I wasn't specifying a version.  As a test, I tried 
> > > changing the 'camel-jaxb-starter' version to several things, going all 
> > > the way back to version 2.18.0, but that didn't solve my problem.
> > >
> > > Strange.....
> > >
> > > I'm going to have to come up with some other trick to hang on to the body 
> > > - so that I can reset the body - so that I can attempt the 2nd unmarshal.
> > >
> > > Wish me luck....
> > >
> > > > On June 25, 2019 at 9:50 AM Michael Davis <michael.da...@solace.com> 
> > > > wrote:
> > > >
> > > >
> > > > Can you get the sender to specify which type of file it is using a 
> > > > particular topic or message header or something?
> > > >
> > > > Michael Davis
> > > >
> > > > On 2019-06-21, 5:29 PM, "Ron Cecchini" <roncecch...@comcast.net> wrote:
> > > >
> > > >     Hey, all.
> > > >
> > > >     I have a route that's sitting on a port and it can receive 1 of 2 
> > > > different XML messages.
> > > >
> > > >     I was simply going to try to unmarshal with the first one, and if 
> > > > it errors, unmarshal with the next one.
> > > >
> > > >     But is there a smarter or best practices way to handle this?
> > > >
> > > >     Thanks.
> > > >
> > > >
> > > >
> > > >
> 
> 
> 
> -- 
> Claus Ibsen
> -----------------
> http://davsclaus.com @davsclaus
> Camel in Action 2: https://www.manning.com/ibsen2

Reply via email to