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