Hi, We had a chat on IRC brainstorming how JMS binding can leverage the databinding framework. Please see the transcripts below for more details.
A brief summary: 1) There are two service contracts involved for services or references with JMS bindings: a) The service contract from <interface ...> b) The service contract from the binding (which can be a javax.jms.MessageListener). 2) We may need an interceptor to do ServiceContract mapping. For example, it uses the OperationSelector to map a JMS message to a given operation on the interface. 3) Databinding options are exploited. There may be two options: a) For reference, transform the Object[] into an intermediate format such as XMLString, the JMS binding code will construct the Message. For service, the JMS binding code will extract the XMLString from the Message and the databinding framework will transform the XMLStrings into Object[]. b) A transformer transforms the Object[] into a Message and vice versa. This requires that the JMS Session accessible from the transformation context. Thanks, Raymond (3:07:50 PM) rajith_home: rfeng, hello (3:09:27 PM) dkulp left the room (quit: Remote closed the connection). (3:12:05 PM) rfeng: rajith? (3:12:42 PM) rajith_home: rfeng, can you please answer the question on databinding sent to the list. (3:12:49 PM) rfeng: just came back from a training class (3:12:57 PM) rfeng: sure, I'll (3:13:00 PM) rajith_home: rfeng, I still feel that I haven't understood the whole concept (3:13:06 PM) rfeng: ok (3:13:16 PM) rajith_home: rfeng, thansk raymond and sorry for bugging you (3:13:16 PM) rfeng: which part? (3:13:20 PM) rfeng: np (3:14:00 PM) rajith_home: rfeng, I need to understand where I have to indicate the expected data type (3:14:39 PM) rajith_home: rfeng, so then in the target invoker and in my service I can work with my prefered data type and let the framework do the conversion (3:15:08 PM) rfeng: let's put this way (3:15:28 PM) rfeng: you're implementing a JMS binding (3:15:42 PM) rajith_home: rfeng, now axis2 works with AXIOM, but I want to work with Object[] for invoking methods, but I want to serialize them to xml when I send them over the wire (3:15:46 PM) rajith_home: rfeng, sorry go ahead (3:15:59 PM) rfeng: for reference (outbound) and service (inbound), right? (3:16:10 PM) rajith_home: yes (3:16:22 PM) rfeng: let's start with the reference (3:16:44 PM) rfeng: assuming you use java interface to model your reference (3:17:05 PM) rfeng: or WSDL? (3:17:24 PM) rajith_home: I use java interface (3:17:27 PM) rfeng: ok (3:18:13 PM) rfeng: there is an operation: String concat(String s1, String s2) (3:18:24 PM) rajith_home: ok (3:18:26 PM) rfeng: how do you want to create the JMSMessage? (3:19:24 PM) rajith_home: ok, the operation name is send as a jms property, and the arguments should be serialized (XML, java serialization...etc), but XML is preffered. The arguments are sent as the jms payload (3:19:36 PM) rfeng: component1.ref1 --> composite.reference w/ JMS binding --> JMS layer (3:19:46 PM) rajith_home: yep (3:21:03 PM) rfeng: so the JMS binding builder will tell me the native ServiceContract for the JMS layer (3:21:28 PM) rajith_home: ok thats a part I missed (3:21:36 PM) rajith_home: now where does the conversion happen, and what do I have to do to get the required conversion from say object[s1,s2] to some xml serialization (3:21:52 PM) rajith_home: so I need to specifiy the native format ? (3:22:29 PM) rfeng: if you tell me that the native format is XMLString (3:23:22 PM) rajith_home: it is XML string, btw how do u specifiy this in the binding builder? (3:24:00 PM) rfeng: The databinding interceptor on the outbound wire of the reference will find a transformer which can convert s1, s2 into xml (3:25:16 PM) rfeng: in your case, really you don't have a ready-to-use ServiceContract for the JMS layer, so maybe clone the JavaServiceContract and call setDataBinding() (3:25:55 PM) rfeng: maybe we should transform the Object[] as a whole (3:26:03 PM) rfeng: right now it's arg by arg (3:26:10 PM) rajith_home: ok I see (3:26:15 PM) rajith_home: so in my target invoker what should I expect then for the payload? (3:26:27 PM) rfeng: but you can claim the JMS contract is wrapped (3:27:07 PM) rfeng: and the JMSDataBinding will provide a wrapper handler (3:27:23 PM) rfeng: in your case, the wrapper can be the JMSMessage (3:27:33 PM) rfeng: and args are children (3:28:29 PM) rajith_home: so u mean I pass in the arguments and the JMSDataBinding class will return me a JMS Message? (3:28:34 PM) jboynes: the wrapper being a transform that converts Object[] to JMSMessage? (3:29:00 PM) rajith_home: LOL, same idea (3:29:10 PM) rfeng: yes (3:29:16 PM) rajith_home: well to be honest thats more inline with the spec (3:29:48 PM) rajith_home: so I register my JMSDataBinding with the registry as another framework? (3:30:10 PM) rajith_home: like sdo,xmlbeans, jaxb.axiom ..etv (3:30:14 PM) rfeng: so the JMSMessageDataBinding will register itself with the DataBindingRegistry (3:31:21 PM) rfeng: the incoming data is Object[] (unwrapped) (3:31:23 PM) rajith_home: hmm makes more sense now, and I can use what ever serialization I want for the objects when I implement the JMSDataBinding (3:31:37 PM) rfeng: and if we detect the target operation is wrapped (3:32:01 PM) rfeng: we lookup the WrapperHandler (from DataBinding) (3:32:35 PM) rfeng: then call create() to create the wrapper (in your case JMSMessage) (3:32:53 PM) rfeng: then call setChild(wrapper, child ,...) (3:33:18 PM) jboynes: rfeng: I hate to ask, but why is wrapping special? (3:33:29 PM) rajith_home: rfeng, to create a JMS message we need to have access to a jms session, so my data binding class needs to be given a session, so is that dependency acceptable? (3:33:40 PM) jboynes: isn't it just another data transform? (3:33:57 PM) rfeng: it's another data transform (3:34:34 PM) rfeng: we have Input2Input, Output2Output transformers which deal with it (3:34:49 PM) jboynes: ok (3:34:51 PM) jboynes: cool (3:34:57 PM) tsee [EMAIL PROTECTED] entered the room. (3:35:18 PM) jboynes: I was confused by create() and setChild() - it sounded like there was a different api (3:35:49 PM) rfeng: That's used to define the wrapping capabilities from different databindings (3:35:51 PM) rajith_home: ok, I got lost again, what did u mean by Object[] (unwrapped) ? (3:36:25 PM) bhdaniel left the room (quit: Read error: 145 (Connection timed out)). (3:36:30 PM) rfeng: meaning each element in the Object[] is the real arg (3:36:41 PM) rfeng: (s1, s2) (3:37:11 PM) rfeng: I guess there're two choices for JMS case (3:37:34 PM) rajith_home: rfeng, ok and if the target operation is expecting a JMS message then we need to wrap the args inside a JMS message (3:37:42 PM) rfeng: 1) convert (s1, s2) to an intermediate format and the target invoke will take that to create the JMSMessage (3:38:05 PM) rfeng: 2) Directly convert (s1,s2) to a JMSMessage (3:38:25 PM) rajith_home: rfeng, convert to XML and give it to me so I can transport it inside a JMS message (3:38:35 PM) rfeng: which one do you prefer? 1? (3:38:55 PM) rajith_home: option 2 mean my JMSDataBinding class needs access to a jms session to create the message (3:39:01 PM) rfeng: yes (3:39:07 PM) rajith_home: rfeng, so option 1 is better (3:39:11 PM) rfeng: ok (3:39:22 PM) rfeng: then it could be simpler (3:40:13 PM) rajith_home: rfeng, jboynes do we need to support the case where the target component is expecting a message? if thats the case then the target component needs to know how to parse the payload (3:40:46 PM) rajith_home: rfeng, jboynes which is not every elegant in my opinion. (3:41:27 PM) jboynes: don't get that (3:41:32 PM) rajith_home: rfeng, os it's better if [s1,s2] --> xml --> jms msg --> xml --> [s1,s2] (3:41:57 PM) jboynes: I think option 2 sounds better (3:42:09 PM) rfeng: :-) (3:42:17 PM) jboynes: s1, s2 could convert to XML using different serializers (3:42:42 PM) rajith_home: jboynes, well if the target component has a operation like onMessage(javax.jms.Message message) then it needs to know how to parse the payload and extract the arguments or business data (3:42:53 PM) jboynes: so [s1,s2] -> [x1, s2] -> [x1, x2] -> JMSMessage (3:43:25 PM) jboynes: rajith_home: if that's its service contract then that would be what it was expectinvg (3:43:56 PM) rajith_home: jboynes, agreed also if people want [s1,s2] --> java serialized --> bytes message --> java serialized --> [s1,s2] (3:44:20 PM) jboynes: yes (3:44:22 PM) rfeng: I think the reference and service side can be asymtric (3:44:42 PM) jboynes: yes (3:45:32 PM) rajith_home: jboynes, if it expects a message directly then the component invoking the reference will obviously needs to send some business data in the payload in a format the target component understands (3:45:35 PM) rfeng: s1, s2 --> jms .... jms ... --> SDO, SDO (3:46:02 PM) jboynes: it would depend on what the target component was doing with the message (3:46:09 PM) jboynes: it may never need to deserialize the payload (3:46:19 PM) rfeng: right (3:46:20 PM) jboynes: it may just be forwarding it on (3:46:48 PM) jboynes: but another component might want us to do the deserialization (3:46:58 PM) rfeng: the JMSMessage is picked up the service and delegate downstream to target component (3:47:12 PM) jboynes: but in that case it would not be expecting a Message but one or more bits of business data (3:48:19 PM) jboynes: it may even expect a combination (3:48:33 PM) jboynes: doStuff(Message msg, Order payload) (3:50:04 PM) rfeng: Assume this flow: JMS --> (service.binding) Message --> (service.interface SDO) --> (component.interface, Message) (3:51:12 PM) rfeng: by default, it goes from Message to SDO and then back to Message (not sure the 2nd part is possible) (3:51:31 PM) rfeng: but we can optimize to have Message --> Message (3:52:01 PM) rfeng: because the service.interface is for wiring purpose (3:53:21 PM) rfeng: jboynes, we may have to transform Object[] as a whole in generic cases (3:53:28 PM) rfeng: instead of arg by arg (3:54:14 PM) rajith_home: jboynes, rfeng extreamly sorry I had to change me kids diaper :-) (3:54:23 PM) rajith_home: jboynes, rfeng sorry for the delay (3:54:35 PM) rfeng: np, I do the same job (3:54:42 PM) rajith_home: LOL (3:54:52 PM) jboynes: one is tempted to say s**t happens (3:55:05 PM) rfeng: :-) (3:55:06 PM) jboynes: sorry (3:55:18 PM) rajith_home: jboynes, and it happens during the most important conversations (3:56:18 PM) jboynes: back on track, rfeng why would generics make a difference? (3:56:39 PM) rfeng: didn't mean to java generics (3:56:53 PM) jboynes: ah (3:57:32 PM) rfeng: I'm thinking of the case that transform from Object[] to another Object[] (the size can be different) (3:58:27 PM) rfeng: for the wrapping case, we transform Object[n] to Object[1] (the only child is the wrapper) (3:58:29 PM) jboynes: wouldn't arg-by-arg just be a series of Object[] transforms (3:58:56 PM) jboynes: Object[s1, s2] -> Object[t1, s2] (3:59:13 PM) rfeng: yes it is (3:59:29 PM) rajith_home: ok so we need to handle the message --> message case and then object[] ---n transformations -- object[] ? (3:59:47 PM) jboynes: so its a transform of an Object[] to an Object[] with different contnt (3:59:52 PM) jboynes: content (3:59:58 PM) rajith_home: yes (4:00:03 PM) rfeng: yes (4:00:47 PM) tsee left the room (quit: Read error: 110 (Connection timed out)). (4:00:54 PM) rajith_home: but when u code the invoker and the service which data type should u work with? thats where I am convinced, what should expect in the payload in the invoke method (4:01:04 PM) rfeng: so the incoming data is Object[] {s1, s2} (4:01:20 PM) jboynes: rajith_home: which invoker? (4:01:20 PM) rfeng: then it got converted to {Message} if we follow option 2 (4:01:34 PM) rajith_home: sorry conviced should be changed to confused :-) (4:02:04 PM) rfeng: then the target invoker should just send the Message out (4:02:34 PM) rajith_home: JMSTargetInvoker invoke() (4:02:55 PM) jboynes: rfeng: you're saying the target invoker for the JMS binding should expect to have a Message in the payload (4:02:57 PM) jboynes: ? (4:03:13 PM) rfeng: for option 2 (4:03:18 PM) jboynes: or actually, can assume it has a Message in the payload (4:04:05 PM) rfeng: what's the difference? (4:04:08 PM) lresende [EMAIL PROTECTED] entered the room. (4:04:14 PM) jboynes: none (4:04:23 PM) jboynes: just trying to clarify my phrasing (4:04:30 PM) rajith_home: jboynes, so does it mean that we have a transformer registered that will convert this object array into some serialized format and then shove it into a jms message? (4:04:37 PM) rfeng: ok, that's what I meant. (4:04:52 PM) jboynes: I think that would be a set of transformers but yes (4:05:28 PM) rfeng: it could be a transformer invoking other transformers (4:05:44 PM) rfeng: using the mediator interface (4:05:59 PM) jboynes: or just a transform pipeline? (4:06:15 PM) rajith_home: can we defined the path using these transformers, for example [s1,s2] --> some xml --> JMS message ? (4:06:27 PM) rfeng: yes (4:06:59 PM) rajith_home: rfeng, where is that defined ? in the code? or in some config ? (4:07:32 PM) rfeng: let's assume the java interface for your JMS reference is annotated with SDO databinding (4:08:49 PM) rfeng: then we try to convert the SDO input to XMLString (expressed by the JMS binding) using SDO-->XMLString transformer (4:10:09 PM) rajith_home: rfeng, ok (4:10:23 PM) rfeng: jboynes, a related question here (4:10:52 PM) jboynes: ok? (4:11:07 PM) rfeng: if I have an operation say String doSomething(DataObject, String, Customer) (4:11:22 PM) rfeng: it seems that operation level databinding is not good enough (4:11:52 PM) rfeng: for me to identify which arg needs to convert (4:12:37 PM) jboynes: unless you are assuming SDO throughout, no (4:12:54 PM) jboynes: if Customer is e.g. JAXB then you need per-arg (4:13:03 PM) rfeng: should we add the parameter-level databinding back? (4:13:35 PM) rajith_home: rfeng, I thought we don't support mixed argument types (4:13:43 PM) rfeng: I also have a simple case such as op(String str1, String str2) (4:13:49 PM) jboynes: i think the reason it was dropped was that we didn't think anyone would be crazy enough to do that ;-) (4:14:10 PM) rfeng: and I expect str1 is XML but str2 is a plain string (4:14:33 PM) rfeng: I don't have a way to express that (4:15:14 PM) jboynes: physical type String, logical type an element QName ? (4:15:41 PM) rfeng: yes, but it cannot be expressed at operation level (4:16:06 PM) jboynes: oh (4:16:09 PM) rfeng: because for str2, I want to have (String, String, java-data-binding) (4:16:39 PM) rfeng: meaning no conversion will apply to str2 (4:17:04 PM) jboynes: sounds like per-arg is not that crazy after all (4:17:13 PM) rfeng: I found it different to decide which arg needs to convert (4:17:26 PM) rfeng: or not to convert (4:18:05 PM) rfeng: for WSDL portType, seems to be fine with interface-level databinding (4:18:46 PM) rfeng: because its types are usually modeled using XSD, and there should be a XML binding behind it (AXIOM, DOM, JAXB or SDO) (4:19:18 PM) rfeng: for java interface, it's a bit challenging (4:19:26 PM) rajith_home: exactly (4:19:52 PM) rajith_home: so do I have to support per argument level data binding for jms binding as well? will it makes sense? (4:20:17 PM) rfeng: I don't think so (4:21:00 PM) rfeng: to me , the JMS message is a carrier of business data which is transparent to other components (4:21:04 PM) rajith_home: I guess the simple case of [s1,s2] --> intermediate --> jms --> intermediate --> [t1,t2] is fine (4:21:12 PM) rajith_home: yes (4:21:57 PM) rfeng: if you express the requirement of an intermediate format, the wiring fabric can convert for you (the jms binding code) (4:22:51 PM) rajith_home: u mean my JMSDataBinding code will convert from the object[] to lets say XML and vice verca ? (4:23:20 PM) rajith_home: rfeng, do u prefer that route (4:24:15 PM) rfeng: what's your requirement on the Object[]? (4:24:46 PM) rfeng: if you use the java interface to define a reference with JMS binding? (4:25:11 PM) rfeng: I mean the expectation from the JMS binding side? (4:25:45 PM) rajith_home: for example [string, int, string] just simple data types and the target component expects the same (4:25:59 PM) jboynes: i would think there would be multiple JMS data bindings (4:26:22 PM) jboynes: in that case what would the message be? (4:26:43 PM) jboynes: I can see Object[string, int, string] -> ObjectMessage (4:27:07 PM) rajith_home: the operation name is mapped as a jms propert and the the arguments serialized as the payload (4:27:27 PM) jboynes: and Object[string, int, string] -> DOM(foo:msg) -> TextMessage containing XML (4:27:38 PM) rajith_home: the serialization could be xml or java serialization so it could be a text msg or object or even bytes msg (4:27:44 PM) rfeng: maybe we should follow the java 2 WSDL doc-lit wrapper mapping (4:27:56 PM) rfeng: then we have clean data contract (4:28:30 PM) jboynes: rajith_home: in that case isn't the operation name a constant value (4:28:38 PM) jboynes: added to the specific bindng (4:28:55 PM) jboynes: and the binding would insert that to the Message (4:30:03 PM) rajith_home: yes the binding defines a operation selector (4:30:17 PM) jboynes: yes (4:30:38 PM) rajith_home: the op selector decides how to encode the operation name and also how to extract it from the jms message (4:30:44 PM) jboynes: we could actually implement that as an interceptor/transform (4:31:18 PM) jboynes: the binding service contract could be onMessage(Message) (4:31:48 PM) rfeng: yes (4:32:01 PM) jboynes: and an interceptor routes that to a different chain based on content of the message (4:32:19 PM) jboynes: e.g. using the supplied OperatonSelector (4:32:36 PM) rajith_home: yes, if thats the case then it doesn't make sense to encode the operation name in the jms message and the payload will contain business data instead of encoded arguments (4:33:01 PM) jboynes: lost me there (4:33:31 PM) rajith_home: sorry I replied to "the binding service contract could be onMessage(Message)", didn't see your latest post (4:34:02 PM) jboynes: ah (4:34:57 PM) rajith_home: so the operation selector acts as a transformer? but it doesn't define any data transformation right? it mearly describes how to encode/decode the operation name from a message (4:35:35 PM) jboynes: I think its more of an interceptor (4:35:38 PM) rajith_home: so I am not sure if the op sec qualifies as a transformer. maybe I didn't understand your point (4:35:50 PM) rfeng: do you expect the JMSMessage from other non-SCA client? (4:36:03 PM) rajith_home: thats the intention of the spec group (4:36:09 PM) rfeng: ok (4:36:29 PM) rfeng: then we need to have a well-defined wire format for JMS message? (4:36:36 PM) rajith_home: specially we could be accessing a non SCA resource like some legacy JMS application (4:36:39 PM) jboynes: I'm thinking there are two service contracts in the Service with a JMS binding (4:36:55 PM) jboynes: the first is MessageListener (4:36:58 PM) rfeng: seems so (4:37:05 PM) jboynes: that's the binding contract (4:37:10 PM) rfeng: 2nd is mapped interface (4:37:19 PM) jboynes: the other is the Service's interface e.g. Foo.class (4:37:33 PM) jboynes: as defined by the <interface> (4:37:40 PM) rfeng: yes (4:38:10 PM) jboynes: the first part of the interceptor stack converts between those two contracts (4:38:55 PM) rajith_home: jboynes, when I coded the JMS service I register it as a JMS listener, it picks up the message and invoke a java interface after converting the payload into an object[] (4:39:04 PM) jboynes: e.g. using an interceptor to call the OperationSelector to map from onMessage to the operation in Foo (4:39:30 PM) rfeng: what invocation chain is the interceptor added? (4:39:43 PM) rfeng: the fixed onMessage operation? (4:39:47 PM) jboynes: yes (4:40:01 PM) jboynes: it maps from one chain to many (4:40:14 PM) rfeng: ok (4:40:23 PM) jboynes: rajith_home: we're trying to cut out the prozy invoke (4:40:29 PM) jboynes: s/prozy/proxy/ (4:40:40 PM) rfeng: one inbound chain to many outbound chains to the target component (4:41:06 PM) jboynes: hmm (4:41:09 PM) rajith_home: jboynes, I see (4:41:22 PM) jboynes: one inbound chain to many inbound changes to the Service (4:41:28 PM) jboynes: s/changes/chains/ (4:43:00 PM) rfeng: why do you need to have many inbound chains in this case? (4:43:01 PM) rajith_home: jboynes, so if we cut the proxy invoke then we always have fixed operation as rfeng suggested. So onMessage()? (4:43:31 PM) jboynes: for the binding contract yes (4:43:50 PM) jboynes: as that is the interface we are exposing to the JMS implementation (4:43:57 PM) rfeng: right (4:44:23 PM) rajith_home: rfeng, jboynes I need to go pick up my wife from school, I really hate to leave in the middle of a conversation, but have no choice (4:44:32 PM) jboynes: [ I'm going to have to cut and run in a bit - no diapers, collecting kid from school ] (4:44:33 PM) rfeng: sure, np. (4:44:39 PM) jboynes: me too (4:44:46 PM) jboynes: sounds like a good time to take abreak (4:44:48 PM) rfeng: I'll think more (4:44:50 PM) rajith_home: rfeng, jboynes cool (4:45:01 PM) rfeng: ttyl (4:45:02 PM) jboynes: rfeng: as the last survivor, can you summarize/post this to the list (4:45:09 PM) jboynes: please (4:45:09 PM) rfeng: sure (4:45:14 PM) jboynes: thanks (4:45:18 PM) rajith_home: are u guys comming to apache con? (4:45:29 PM) jboynes: i think I am (4:45:36 PM) jboynes: not confirmed yet (4:46:18 PM) rajith_home: we need to come to some resolution on the data binding stuff and the binding contract before I move any forward :-( (4:47:20 PM) rajith_home: ant has the patch commited to ../sandbox/rajith... so feel free to dig in and change stuff if u guys wanna experiment (4:47:36 PM) rajith_home: rfeng, jboynes bye guys and thanks for the support