camel-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From James Strachan <>
Subject Re: [DISCUSS] Semantics of IN and OUT (was: Faults and Exceptions in Camel)
Date Tue, 14 Jul 2009 09:54:56 GMT
2009/7/14 Roman Kalukiewicz <>:
> 2009/7/14 James Strachan <>:
>> 2009/7/13 Claus Ibsen <>:
>>>> Reading between the lines; are you really just trying to make folks
>>>> use (what is currently called) "getOut()" and never try mutate what is
>>>> currently called getIn()?
>>>> i.e. so by default the "OUT" property is defaulted to a copy of IN
>>>> that folks can change/mutate.
>>>> (what we call these 2 methods is a separate discussion, whether its
>>>> "in,out" or "originalMessage,message" or whatever
>>> Hadrian and I had a chat today and we are clearing up some bits.
>>> I am more on line with him now on the IN and OUT thing.
>>> So lets keep them.
>>> And use the time to fix the tiny bits such as the getOut() doing its
>>> lazy creating a new empty message.
>>> And whether its possible to let IN be immutable.
>> I think we're kinda mostly on the same page (though saying it in
>> different ways). BTW I'm taking off my devils advocate hat now :)...
>> What we're agreeing on I think is that;
>> * getIn() should be immutable (when folks try to change it we can
>> throw the exception and describe how getOut() should be used to change
>> the message) - to prevent folks using the old code (which will require
>> code changes).
> Definitely agree.
>> * having the original immutable message available is handy; but mostly
>> folks should concentrate on the 'out' (current name today)
> It is handy.But the question is if we should add another message while
> both client and processor implementor can store original message (body
> or headers he wants) in a variable if they only want to store them. Do
> we have to store those things for them no mater if they need it or
> not? This comment applies only if we want to have IN message on
> processor level (every processor receives its new IN message).
> I personally don't see a huge difference between:
> Object oldBody = exchange.getMessage().getBody();
> template.send(exchange);
> Object newBody = exchange.getMessage.getBody();
> and
> template.send(exchange);
> Object oldBody = exchange.getOriginalMessage().getBody();
> Object newBody = exchange.getMessage().getBody();
> while the second one complicates an API by having additional method on
> the exchange.
>> * the out should be automatically populated with a clone of the IN (to
>> avoid all that pain with checking if there's an out or an in, or the
>> possible loss of headers etc. Internally we can use a CopyOnWrite
>> facade to reduce the cost of potentially copying a message which is
>> not actually mutated.
> True
>> Given that; I think we're mostly agreeing. However given the confusion
>> of getIn() and getOut() I'm wondering if actually your previous idea
>> of changing the api of exchange to have a getMessage() which returns
>> the thing a processor should be changing; then having a
>> getOriginalMessage() (which can be null if you are the first in the
>> chain) might reduce the amount of confusion?
> Because of previous comment about IN messages I believe that maybe we
> should have getOriginalMessage() that returns an original message as
> JMS Message, JBI Exchange and so on. This assures that users can
> always reach full information they received. It would look like
> from("jms:q1")  // Original message contains JMS message received
> .transform(expression) // Still original JMS message - no endpoint involved
> .setHeader("foo", expression) // Still original JMS message - still I
> can reach some JMS specific things
> .to("jbi:service") // Now I have JBI exchange in original message
> .bean(myBean) // My Bean reaches exchange directly to reach some stuff
> from ServiceMix specific JBI exchange
> .to("jms:q2") // JMS response message in original message
> .to("direct:end") // Camel Exchange in original message as it is now
> endpoint specific type
> .to("seda:foo") // InOnly operation. I'm not sure if it should be null
> in original message, or maybe nothing modified.
> I propose it because I don't really like our custom Message
> subclasses. They tend to mirror Camel message model and some
> underlying technology's model. But sometimes they are not compatible
> really and strange things happen. But maybe this is the discussion for
> another thread?
>> i.e. after sleeping on it, I'm warming to the idea of renaming getIn()
>> -> getOriginalMessage() and getOut() -> getMessage(). (Or maybe
>> getInputMessage() for getIn()?)
>> Thoughts?
> I definitely agree that for the moment we can add those methods,
> deprecate getIn()/getOut() and let them simply return getMessage().
> To summarize my ideal model is (helpers like getBody(Class) omitted):
> CamelMessage
> Object get/setBody() //obvious
> Map<String, Object> getHeaders() // for technology specific headers
> received/sent
> Map<String, Object> getProperties() // for business specific
> information that is generally not touched by endpoints - user can
> store there any information he wants to be sent through the flow and
> not be lost at the endpoint
> Object get/setOriginalMessage() // For technology specific message
> representation like JMS Message/JBI Exchange
> Exception get/setException() // For exception handling
> boolean is/setFault() // For business fault detection
> In a model where only one message exists, exchange is not even needed.
> Heh - I feel guilty for enlisting all those things now while it looks
> that an agreement on API changes exists ;)
> Maybe a proposal for 2.1? ;)

FWIW I still like the Exchange being there as a holder of the Message;
as folks can then, if they want, create a totally new, empty Message
and set it on the Exchange (rather than just mutating the incoming


Open Source Integration

View raw message