I have plenty of endpoints based on POST/PUT where the message body already contains important information, so I've been using headers or properties to add information without needing to make the body itself a map or some other wrapper. If this isn't the proper way to use camel, then I'd like to hear about it because sometimes I feel like I'm missing something here. The DSL certainly makes it easier to manipulate headers and properties than it does the body.
On 6 July 2016 at 10:03, Brad Johnson <brad.john...@mediadriver.com> wrote: > But if you are using CXFRS then you can make the databean itself contain > what I'll call initializable data. This isn't a bad example but you get > the idea. > > public void setFirstName(String firstName) > { > if(this.firstName==null) this.firstName=firstName; > //Maybe throw an exception if it is already set. > } > > So the first time that data can be set but after that it is immutable. > Since the path query params are items you can access via the annotations > you can use them to do the initial setting on the data. Part of this, from > my perspective, is that when I move from REST to Java objects I almost > always want that query data in my data objects themselves. If I'm updating > a contact by first name (can't imagine that ever being a use case so SSN > was probably a better choice) then the firstName query parameter is > probably something I'm going to set on my Contact data object. Or worst > case the path and the data object will both have that data. After that all > my routing is based on the Contact object and other logical concerns and > not on REST or SOAP or other header information that I haven't already > tucked inside the data object. > > I believe one can also specify that JAXB set the data by fields during > marshaling/unmarshaling. And then the setters for some of the critical > fields can actually be no-ops or throw exceptions. > > None of that may be pertinent to the REST DSL however as I don't use it or > know it. But I almost never exclusively program REST only APIs and so the > solutions I use in Camel can't count on or use REST only mechanics. In a > way I think that's an abstraction leak. The HTTP verbs, query params, and > so on shouldn't make it past the endpoint. None of the routing or logic > should care whether the data came from REST, SOAP, JMS or wherever. > > And certainly if you us an immutable bean in the header it could be > replaced by a gremlin programmer. But if that bean has no functional > purpose other than to do sanity checking to ensure that the headers haven't > been mutated then nobody would really have any reason to ever do that. And > if you wanted to carry it one step further you could have that immutable > object generate a UUID and put that in a correlationID header that you > could use to verify that that the immutable bean hadn't been replaced. If > it had the ID wouldn't match up. So that correlationID and immutable bean > wouldn't have any functional purpose that a developer would ever use them > for except in ones unit tests and perhaps at the end of the routes to > verify that everything went right. > > I've also found in these situations that I make sure I'm on top of the > routing and the one who is writing all that code as a crosscutting concern > to all the projects so that if the developers mess with data they shouldn't > and that will change the routing then it will end up breaking hard. > > > > On Tue, Jul 5, 2016 at 6:36 PM, Matt Sicker <boa...@gmail.com> wrote: > > > I actually used to use CXFRS in this application (you can still see > > remnants of it like using the header "operationName" to route from a REST > > endpoint to an ActiveMQ queue). Even if I used an immutable bean in the > > header, that bean could still be replaced. It seems like the only way to > > implement a truly immutable header or property would be an addition to > the > > camel-core API, and I'm not so sure if such a feature would be accepted. > > > > On 5 July 2016 at 18:20, Brad Johnson <brad.john...@mediadriver.com> > > wrote: > > > > > I've always used CXFRS so don't have any experience with the REST DSL > > > itself. With CXFRS I usually end up binding everything to the data > object > > > when it first comes in and that does remain immutable so I don't end up > > > working with headers for any data elements. By using the same interface > > for > > > both my SOAP and REST and binding it this way. The only requirement > then > > > is that the data bean have @XmlRootElement specified so that JAXB knows > > how > > > to handle it. For the routing I then use the recipientList along with > the > > > method name so that it is disconnected from either SOAP or REST. I'm > > > making this example up off the top of my head so don't hold me to the > > > specifics. > > > > > > @WebMethod(operationName = "updateContact", action = "") > > > @WebResult(name = "Contact", targetNamespace = "") > > > @PUT > > > @Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML}) > > > @Consumes({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML}) > > > @Path("contact/{firstName}") > > > public Contact updateContact(Contact contact) { > > > ... > > > } > > > > > > Then in the CXF blueprint file I'll put something like this: > > > > > > <recipientList> > > > <simple>direct-vm:${header.operationName}</simple> > > > </recipientList> > > > > > > > > > In this case when that interface is invoked it equates to the defined > > > "operationName" on a direct-VM but that could be any transport. > > > > > > So calling that method invokes direct-vm:updateContact and that's > where I > > > start the route handling. But by that time the data is firmly bound to > > the > > > bean and is not mutable. > > > > > > But you could, at the very least, create wrapper class with immutable > > > fields on it that you could instantiate and save in the header as the > > first > > > step in the process. That would prevent any modification of those > > > variables and at least help in debugging when something goes wrong. > Why > > > didn't this go where it was supposed to? Catch the exception and then > > pull > > > the original bean with immutable fields and see what it says the values > > > should be compared to what they currently are. > > > > > > It sounds like this is going to be a case where you're going to have to > > > rely on some fairly rigorous testing to make sure nobody is doing > > anything > > > stoopid. > > > > > > > > > On Tue, Jul 5, 2016 at 4:03 PM, Matt Sicker <boa...@gmail.com> wrote: > > > > > > > Let me give a more specific use case. Path parameters from rest-dsl > are > > > > passed in as message headers. I don't want any route to accidentally > > > > overwrite or modify those headers as they're useful for the entire > > > > lifecycle of that message. > > > > > > > > On 5 July 2016 at 16:00, Matt Sicker <boa...@gmail.com> wrote: > > > > > > > > > The exact use case is preventing developers from [inadvertently] > > > > modifying > > > > > headers or properties that are used before and after a particular > > > > subroute. > > > > > > > > > > On 5 July 2016 at 15:57, souciance < > souciance.eqdam.ras...@gmail.com > > > > > > > > wrote: > > > > > > > > > >> I guess the question is, why would different routes split over > > > different > > > > >> bundles want to write over the same header/property? What's the > case > > > > here? > > > > >> Surely it cannot be just to prevent accidents by developers > because > > > what > > > > >> would be their reason to write over that header? > > > > >> > > > > >> I think it is better to agree on a naming and some sort of other > > > > >> convention > > > > >> and stick to that because I don't think there is a way to to make > a > > > > header > > > > >> immutable. I guess an ugly solution would be to save the header > in a > > > map > > > > >> and give the key name something very unique. > > > > >> > > > > >> On Tue, Jul 5, 2016 at 10:48 PM, Matt Sicker [via Camel] < > > > > >> ml-node+s465427n578481...@n5.nabble.com> wrote: > > > > >> > > > > >> > Please let me know if you think of anything! > > > > >> > > > > > >> > On 5 July 2016 at 15:16, Brad Johnson <[hidden email] > > > > >> > <http:///user/SendEmail.jtp?type=node&node=5784811&i=0>> wrote: > > > > >> > > > > > >> > > I certainly understand the impulse and think it is spot on but > > > can't > > > > >> > think > > > > >> > > of how to do it with headers. Claim checks might work but > they > > > are > > > > >> > really > > > > >> > > for reducing overhead of data and not for locking like that > but > > > that > > > > >> > might > > > > >> > > be a viable solution depending on the exact problem. > > > > >> > > > > > > >> > > Thanks Matt, this is going to be stuck in my head now. I'll > > > > probably > > > > >> > dream > > > > >> > > of an answer of some sort tonight. > > > > >> > > > > > > >> > > Brad > > > > >> > > > > > > >> > > On Tue, Jul 5, 2016 at 3:02 PM, Matt Sicker <[hidden email] > > > > >> > <http:///user/SendEmail.jtp?type=node&node=5784811&i=1>> wrote: > > > > >> > > > > > > >> > > > My use case is basically to help prevent bugs where a header > > or > > > > >> > exchange > > > > >> > > > property gets modified. Some of my routes in question branch > > out > > > > >> into > > > > >> > > > several different bundles, and it is difficult to enforce > > > > contracts > > > > >> > that > > > > >> > > > way amongst several developers with varying levels of Camel > > > > >> expertise. > > > > >> > > > Similar to how one might use final variables to prevent > people > > > > from > > > > >> > > > reassigning them, this could be a final header that prevents > > > > people > > > > >> > from > > > > >> > > > reusing them for things. > > > > >> > > > > > > > >> > > > On 5 July 2016 at 14:22, Brad Johnson <[hidden email] > > > > >> > <http:///user/SendEmail.jtp?type=node&node=5784811&i=2>> > > > > >> > > > wrote: > > > > >> > > > > > > > >> > > > > That's what I figured. I'd have to look at the Map > > > > implementation > > > > >> > of > > > > >> > > the > > > > >> > > > > exchange but as far as I know there isn't a way to make > it a > > > > write > > > > >> > once > > > > >> > > > > only operation. It's just a map of some sort. There > might > > > be a > > > > >> way > > > > >> > to > > > > >> > > > do > > > > >> > > > > it with transactions but I'm not an expert there. I > > generally > > > > use > > > > >> > > > headers > > > > >> > > > > but in reality should probably be using exchange > properties > > > more > > > > >> > often. > > > > >> > > > > > > > > >> > > > > > > > > >> > > > > > > > > >> > > > > > > > >> > > > > > > >> > > > > > >> > > > > > > > > > > http://stackoverflow.com/questions/10330998/passing-values-between-processors-in-apache-camel > > > > >> > > > > > > > > >> > > > > Almost any mechanism I can think of off the top of my head > > > could > > > > >> be > > > > >> > > > > subverted by someone who wanted to or who didn't > understand > > > that > > > > >> the > > > > >> > > > value > > > > >> > > > > associated with the bean shouldn't be modified. For > > example, > > > > you > > > > >> > could > > > > >> > > > > create a bean that you associate with your header that > > stores > > > > data > > > > >> > but > > > > >> > > > also > > > > >> > > > > returns a UUID. That UUID could be stored in another > header > > > and > > > > >> > > sometime > > > > >> > > > > later in the routes you could verify that the bean stored > > > under > > > > >> your > > > > >> > > key > > > > >> > > > > returns the same UUID as the header indicates. But that > > > > wouldn't > > > > >> > stop > > > > >> > > > > someone from changing the bean stored to the key and it > > > wouldn't > > > > >> > > prevent > > > > >> > > > > them from updating the UUID to a new bean they might > create. > > > > >> > > > > > > > > >> > > > > On Tue, Jul 5, 2016 at 1:49 PM, Matt Sicker <[hidden > email] > > > > >> > <http:///user/SendEmail.jtp?type=node&node=5784811&i=3>> wrote: > > > > >> > > > > > > > > >> > > > > > I'm thinking of an idea to prevent a header from being > > > > modified > > > > >> by > > > > >> > > > other > > > > >> > > > > > parts of the route. A sort of contract if you will. > > > > >> > > > > > > > > > >> > > > > > On 5 July 2016 at 13:01, Brad Johnson <[hidden email] > > > > >> > <http:///user/SendEmail.jtp?type=node&node=5784811&i=4>> > > > > >> > > > > > wrote: > > > > >> > > > > > > > > > >> > > > > > > Is there another part of your process that is > > specifically > > > > >> > changing > > > > >> > > > the > > > > >> > > > > > > header or are you more concerned about it being > > > consistently > > > > >> > there > > > > >> > > > > across > > > > >> > > > > > > routes? Nothing will change it automatically if it is > > > your > > > > >> > header. > > > > >> > > > I > > > > >> > > > > > > don't remember the actual implementation but > > conceptually > > > it > > > > >> is > > > > >> > > just > > > > >> > > > a > > > > >> > > > > > > hastable/map with key/values. If you set header with > > some > > > > >> > specific > > > > >> > > > key > > > > >> > > > > > > then nothing else will change it. > > > > >> > > > > > > > > > > >> > > > > > > As an example, I use a camel splitter and then set a > > > header > > > > >> with > > > > >> > > the > > > > >> > > > > > > splitter index so that I can use it in another route > > later > > > > to > > > > >> > > > > reassemble > > > > >> > > > > > > with the resequencer. > > > > >> > > > > > > > > > > >> > > > > > > <split> > > > > >> > > > > > > <simple>${body}</simple> > > > > >> > > > > > > <setHeader headerName="seqnum"> > > > > >> > > > > > > <simple>exchangeProperty.CamelSplitIndex</simple> > > > > >> > > > > > > </setHeader> > > > > >> > > > > > > ... > > > > >> > > > > > > > > > > >> > > > > > > The "seqnum" is just a key that I'm defining. I could > > > > >> obviously > > > > >> > > call > > > > >> > > > > it > > > > >> > > > > > > anything "sequenceNumber" or whatever but when I > access > > it > > > > >> later > > > > >> > > that > > > > >> > > > > > > header is available on the exchange. If I explicitly > > > change > > > > >> what > > > > >> > > the > > > > >> > > > > map > > > > >> > > > > > is > > > > >> > > > > > > storing for "seqnum" then it will be different > because I > > > > can't > > > > >> > make > > > > >> > > > the > > > > >> > > > > > > header map itself immutable. > > > > >> > > > > > > > > > > >> > > > > > > > > > > >> > > > > > > On Tue, Jul 5, 2016 at 10:33 AM, Matt Sicker <[hidden > > > email] > > > > >> > <http:///user/SendEmail.jtp?type=node&node=5784811&i=5>> > > > > >> > > > wrote: > > > > >> > > > > > > > > > > >> > > > > > > > As in once I set the header, nothing can change the > > > header > > > > >> > during > > > > >> > > > the > > > > >> > > > > > > > lifecycle of the message during a route. Same for an > > > > >> exchange > > > > >> > > > > property. > > > > >> > > > > > > > > > > > >> > > > > > > > -- > > > > >> > > > > > > > Matt Sicker <[hidden email] > > > > >> > <http:///user/SendEmail.jtp?type=node&node=5784811&i=6>> > > > > >> > > > > > > > > > > > >> > > > > > > > > > > >> > > > > > > > > > >> > > > > > > > > > >> > > > > > > > > > >> > > > > > -- > > > > >> > > > > > Matt Sicker <[hidden email] > > > > >> > <http:///user/SendEmail.jtp?type=node&node=5784811&i=7>> > > > > >> > > > > > > > > > >> > > > > > > > > >> > > > > > > > >> > > > > > > > >> > > > > > > > >> > > > -- > > > > >> > > > Matt Sicker <[hidden email] > > > > >> > <http:///user/SendEmail.jtp?type=node&node=5784811&i=8>> > > > > >> > > > > > > > >> > > > > > > >> > > > > > >> > > > > > >> > > > > > >> > -- > > > > >> > Matt Sicker <[hidden email] > > > > >> > <http:///user/SendEmail.jtp?type=node&node=5784811&i=9>> > > > > >> > > > > > >> > > > > > >> > ------------------------------ > > > > >> > If you reply to this email, your message will be added to the > > > > discussion > > > > >> > below: > > > > >> > > > > > >> > > > > > >> > > > > > > > > > > http://camel.465427.n5.nabble.com/Is-it-possible-to-make-a-message-header-or-property-immutable-tp5784800p5784811.html > > > > >> > To start a new topic under Camel - Users, email > > > > >> > ml-node+s465427n465428...@n5.nabble.com > > > > >> > To unsubscribe from Camel - Users, click here > > > > >> > < > > > > >> > > > > > > > > > > http://camel.465427.n5.nabble.com/template/NamlServlet.jtp?macro=unsubscribe_by_code&node=465428&code=c291Y2lhbmNlLmVxZGFtLnJhc2h0aUBnbWFpbC5jb218NDY1NDI4fDE1MzI5MTE2NTY= > > > > >> > > > > > >> > . > > > > >> > NAML > > > > >> > < > > > > >> > > > > > > > > > > http://camel.465427.n5.nabble.com/template/NamlServlet.jtp?macro=macro_viewer&id=instant_html%21nabble%3Aemail.naml&base=nabble.naml.namespaces.BasicNamespace-nabble.view.web.template.NabbleNamespace-nabble.view.web.template.NodeNamespace&breadcrumbs=notify_subscribers%21nabble%3Aemail.naml-instant_emails%21nabble%3Aemail.naml-send_instant_email%21nabble%3Aemail.naml > > > > >> > > > > > >> > > > > > >> > > > > >> > > > > >> > > > > >> > > > > >> -- > > > > >> View this message in context: > > > > >> > > > > > > > > > > http://camel.465427.n5.nabble.com/Is-it-possible-to-make-a-message-header-or-property-immutable-tp5784800p5784812.html > > > > >> Sent from the Camel - Users mailing list archive at Nabble.com. > > > > > > > > > > > > > > > > > > > > > > > > > -- > > > > > Matt Sicker <boa...@gmail.com> > > > > > > > > > > > > > > > > > > > > > -- > > > > Matt Sicker <boa...@gmail.com> > > > > > > > > > > > > > > > -- > > Matt Sicker <boa...@gmail.com> > > > -- Matt Sicker <boa...@gmail.com>