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