You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by Ron Cecchini <ro...@comcast.net> on 2019/06/21 21:22:55 UTC

How to unmarshal when you don't know what you're unmarshalling?

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.

RE: How to unmarshal when you don't know what you're unmarshalling?

Posted by "Shultz, Dmitry" <Dm...@kaltire.com>.
Hey,

I would use CBR (https://www.enterpriseintegrationpatterns.com/patterns/messaging/ContentBasedRouter.html) + Body check for this.

Cheers
Dmitry

-----Original Message-----
From: Ron Cecchini [mailto:roncecchini@comcast.net] 
Sent: Friday, June 21, 2019 2:23 PM
To: users@camel.apache.org
Subject: How to unmarshal when you don't know what you're unmarshalling?

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.

Re: How to unmarshal when you don't know what you're unmarshalling?

Posted by Ron Cecchini <ro...@comcast.net>.
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 <cl...@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 <ro...@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." <jw...@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:roncecchini@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 <Mi...@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" <ro...@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

Re: How to unmarshal when you don't know what you're unmarshalling?

Posted by Claus Ibsen <cl...@gmail.com>.
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 <ro...@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." <jw...@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:roncecchini@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 <Mi...@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" <ro...@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

RE: How to unmarshal when you don't know what you're unmarshalling?

Posted by Ron Cecchini <ro...@comcast.net>.
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." <jw...@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:roncecchini@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 <Mi...@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" <ro...@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.
> >     
> >     
> >     
> >

RE: How to unmarshal when you don't know what you're unmarshalling?

Posted by "Hart, James W." <jw...@seic.com>.
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:roncecchini@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 <Mi...@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" <ro...@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.
>     
>     
>     
>

Re: How to unmarshal when you don't know what you're unmarshalling?

Posted by Michael Lück <mi...@hm-ag.de>.
Hi,

probably it's best to "marshal" to a generic XML Document, for example org.w3c.dom.Document

exchange.getIn().getBody(Document.class)

Or try to run an XPath expression on the body and decide to which class you need to unmarshal the body. 

Sorry, don't have an example at hand yet.

Regards, Michael 


Am 25. Juni 2019 18:10:00 MESZ schrieb Ron Cecchini <ro...@comcast.net>:
>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 <Mi...@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" <ro...@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.
>>     
>>     
>>     
>>

Re: How to unmarshal when you don't know what you're unmarshalling?

Posted by Ron Cecchini <ro...@comcast.net>.
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 <Mi...@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" <ro...@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.
>     
>     
>     
>

Re: How to unmarshal when you don't know what you're unmarshalling?

Posted by Michael Davis <Mi...@solace.com>.
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" <ro...@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.