2009/7/14 Roman Kalukiewicz <roman.kalukiew...@gmail.com>: > 2009/7/14 James Strachan <james.strac...@gmail.com>: >> 2009/7/13 Claus Ibsen <claus.ib...@gmail.com>: >>>> >>>> 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 one). -- James ------- http://macstrac.blogspot.com/ Open Source Integration http://fusesource.com/