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. > > > > > > > >