-
1. Re: XFire
marklittle Nov 15, 2006 11:18 AM (in response to ruthbd)Not yet. Slow progress, but we'll get there.
-
2. Re: XFire
kconner Nov 15, 2006 11:20 AM (in response to ruthbd)Yes, I have (very recently) received commit access for CXF. The purpose of gaining commit access is to enable the ESB project to work closely with CXF.
Getting JBossTS to work in XFire is not something we have discussed so far, although it would be possible to do this. -
3. Re: XFire
ruthbd Nov 15, 2006 11:20 AM (in response to ruthbd)"mark.little@jboss.com" wrote:
Not yet. Slow progress, but we'll get there.
Have you come across any "issues" with XFire integration, or just need time to get to it? If its the latter, I may take a stab at it myself - we have a vested interest to see if we can get JBossTS working with the XFire dynamic client. -
-
5. Re: XFire
ruthbd Nov 15, 2006 11:33 AM (in response to ruthbd)"Kevin.Conner@jboss.com" wrote:
It is the latter :-)
OK, sounds good. That's not to say I won't come up with issues, but at least none have been discovered so far. -
-
7. Re: XFire
ruthbd Nov 15, 2006 3:56 PM (in response to ruthbd)OK, so - crash course in JDOM ;-)
Looking at XFire handlers & the jax-rpc handlers, the main difference appears to be that in jax-rpc, one works with SOAP abstractions, whereas in XFire, one manipulates the JDOM directly (I could be off-base, but all the examples appear to point to this).
So, to that end, here's the setup/serialization/insertion of the coordination context into the SOAP header, ala XFire:Element coordHeader = new Element( CoordinationConstants.WSCOOR_ELEMENT_COORDINATION_CONTEXT, // localName CoordinationConstants.WSCOOR_PREFIX, // namespace prefix CoordinationConstants.WSCOOR_NAMESPACE); // namespace URI coordHeader.setNamespace(Namespace.getNamespace(CoordinationConstants.WSCOOR_PREFIX, CoordinationConstants.WSCOOR_NAMESPACE)); JDOMStreamWriter out = new JDOMStreamWriter(coordHeader); coordinationContext.writeContent(out); Element xfHeader = message.getOrCreateHeader(); xfHeader.addContent(coordHeader);
Most of the rest of the handler is verbatim from the existing jax-rpc processor. I haven't tested this yet (I need to get my JAX-RPC based test environment working first, so I have a 'control' environment to test against) - but, it looks like this pretty much takes care of what needs to happen in the outgoing handler.
Here's the full class:/** * */ package org.jboss.ts.contrib.xfire.client; import org.codehaus.xfire.MessageContext; import org.codehaus.xfire.exchange.OutMessage; import org.codehaus.xfire.handler.AbstractHandler; import org.codehaus.xfire.util.stax.JDOMStreamWriter; import org.jdom.Element; import org.jdom.Namespace; import com.arjuna.mw.wsc.context.Context; import com.arjuna.mw.wst.BusinessActivityManager; import com.arjuna.mw.wst.BusinessActivityManagerFactory; import com.arjuna.mw.wst.TransactionManager; import com.arjuna.mw.wst.TransactionManagerFactory; import com.arjuna.webservices.wscoor.CoordinationConstants; import com.arjuna.webservices.wscoor.CoordinationContextType; /** * XFireHeaderContextProcessor. * @author BDR011 * */ public class XFireHeaderContextProcessor extends AbstractHandler { /** * @see org.codehaus.xfire.handler.Handler#invoke(org.codehaus.xfire.MessageContext) * @param context * @throws Exception */ public void invoke(MessageContext context) throws Exception { OutMessage message = context.getOutMessage(); if (null == message) { return; } try { /* * There should either be an Atomic Transaction *or* a Business Activity * associated with the thread. */ final TransactionManager transactionManager = TransactionManagerFactory.transactionManager() ; final BusinessActivityManager businessActivityManager = BusinessActivityManagerFactory.businessActivityManager() ; final Context atContext ; if (transactionManager != null) { final com.arjuna.mwlabs.wst.at.context.TxContextImple txContext = (com.arjuna.mwlabs.wst.at.context.TxContextImple)transactionManager.currentTransaction() ; atContext = (txContext == null ? null : txContext.context()) ; } else { atContext = null ; } final Context baContext ; if (businessActivityManager != null) { final com.arjuna.mwlabs.wst.ba.context.TxContextImple txContext = (com.arjuna.mwlabs.wst.ba.context.TxContextImple)businessActivityManager.currentTransaction() ; baContext = (txContext == null ? null : txContext.context()) ; } else { baContext = null ; } final CoordinationContextType coordinationContext ; if (atContext != null) { coordinationContext = atContext.getCoordinationContext() ; } else if (baContext != null) { coordinationContext = baContext.getCoordinationContext() ; } else { coordinationContext = null ; } if (coordinationContext != null) { Element coordHeader = new Element( CoordinationConstants.WSCOOR_ELEMENT_COORDINATION_CONTEXT, // localName CoordinationConstants.WSCOOR_PREFIX, // namespace prefix CoordinationConstants.WSCOOR_NAMESPACE); // namespace URI coordHeader.setNamespace(Namespace.getNamespace(CoordinationConstants.WSCOOR_PREFIX, CoordinationConstants.WSCOOR_NAMESPACE)); JDOMStreamWriter out = new JDOMStreamWriter(coordHeader); coordinationContext.writeContent(out); Element xfHeader = message.getOrCreateHeader(); xfHeader.addContent(coordHeader); } } catch (final Throwable th) { // TODO: handle exception } } }
-
8. Re: XFire
ruthbd Nov 15, 2006 4:25 PM (in response to ruthbd)One other difference between XFire and JAX-RPC w/r/t handlers is that apparently XFire distinguishes between In, Out, and Fault handlers, instead of having a handler that handles the request/response/fault as JAX-RPC does. Regardless of what's being handled, all XFire handlers extend AbstractHandler, so there's probably a way to have one defined Handler process the request/response/fault - but, at the moment, the AbstractHandler just defines an 'invoke()' - so, it would be up to the class to delegate that responsibility, assuming its possible to detect if the In/Out/or Fault chain is being processed.
Anyway - I have created In/Out handlers for both the client & the service. For the client, the "out" handler does the interesting work, the "in" handler just suspends the transaction (what's this do?). For the service, its just the opposite - the "in" handler processes the SOAP header and creates the local CoordinationContextType, the "out" handler just suspends.
None of this is tested yet (it just compiles) - but once I have a working JAX-RPC proof working, I can start testing this.
client.In:/** * */ package org.jboss.ts.contrib.xfire.client; import org.codehaus.xfire.MessageContext; import org.codehaus.xfire.handler.AbstractHandler; import com.arjuna.mw.wst.BusinessActivityManager; import com.arjuna.mw.wst.BusinessActivityManagerFactory; import com.arjuna.mw.wst.TransactionManager; import com.arjuna.mw.wst.TransactionManagerFactory; /** * XFireOutHeaderContextProcessor. * @author BDR011 * */ public class XFireInHeaderContextProcessor extends AbstractHandler { /** * @see org.codehaus.xfire.handler.Handler#invoke(org.codehaus.xfire.MessageContext) * @param context * @throws Exception */ public void invoke(MessageContext context) throws Exception { suspendTransaction(); } /** * Suspend the current transaction. */ private void suspendTransaction() { try { /* * There should either be an Atomic Transaction *or* a Business Activity * associated with the thread. */ final TransactionManager transactionManager = TransactionManagerFactory.transactionManager() ; final BusinessActivityManager businessActivityManager = BusinessActivityManagerFactory.businessActivityManager() ; if (transactionManager != null) { transactionManager.suspend() ; } if (businessActivityManager != null) { businessActivityManager.suspend() ; } } catch (final Throwable th) { // TODO: handle exception } } }
client.Out:/** * */ package org.jboss.ts.contrib.xfire.client; import org.codehaus.xfire.MessageContext; import org.codehaus.xfire.exchange.OutMessage; import org.codehaus.xfire.handler.AbstractHandler; import org.codehaus.xfire.util.stax.JDOMStreamWriter; import org.jdom.Element; import org.jdom.Namespace; import com.arjuna.mw.wsc.context.Context; import com.arjuna.mw.wst.BusinessActivityManager; import com.arjuna.mw.wst.BusinessActivityManagerFactory; import com.arjuna.mw.wst.TransactionManager; import com.arjuna.mw.wst.TransactionManagerFactory; import com.arjuna.webservices.wscoor.CoordinationConstants; import com.arjuna.webservices.wscoor.CoordinationContextType; /** * XFireOutHeaderContextProcessor. * @author BDR011 * */ public class XFireOutHeaderContextProcessor extends AbstractHandler { /** * @see org.codehaus.xfire.handler.Handler#invoke(org.codehaus.xfire.MessageContext) * @param context * @throws Exception */ public void invoke(MessageContext context) throws Exception { OutMessage message = context.getOutMessage(); if (null == message) { return; } try { /* * There should either be an Atomic Transaction *or* a Business Activity * associated with the thread. */ final TransactionManager transactionManager = TransactionManagerFactory.transactionManager() ; final BusinessActivityManager businessActivityManager = BusinessActivityManagerFactory.businessActivityManager() ; final Context atContext ; if (transactionManager != null) { final com.arjuna.mwlabs.wst.at.context.TxContextImple txContext = (com.arjuna.mwlabs.wst.at.context.TxContextImple)transactionManager.currentTransaction() ; atContext = (txContext == null ? null : txContext.context()) ; } else { atContext = null ; } final Context baContext ; if (businessActivityManager != null) { final com.arjuna.mwlabs.wst.ba.context.TxContextImple txContext = (com.arjuna.mwlabs.wst.ba.context.TxContextImple)businessActivityManager.currentTransaction() ; baContext = (txContext == null ? null : txContext.context()) ; } else { baContext = null ; } final CoordinationContextType coordinationContext ; if (atContext != null) { coordinationContext = atContext.getCoordinationContext() ; } else if (baContext != null) { coordinationContext = baContext.getCoordinationContext() ; } else { coordinationContext = null ; } if (coordinationContext != null) { Element coordHeader = new Element( CoordinationConstants.WSCOOR_ELEMENT_COORDINATION_CONTEXT, // localName CoordinationConstants.WSCOOR_PREFIX, // namespace prefix CoordinationConstants.WSCOOR_NAMESPACE); // namespace URI coordHeader.setNamespace(Namespace.getNamespace(CoordinationConstants.WSCOOR_PREFIX, CoordinationConstants.WSCOOR_NAMESPACE)); JDOMStreamWriter out = new JDOMStreamWriter(coordHeader); coordinationContext.writeContent(out); Element xfHeader = message.getOrCreateHeader(); xfHeader.addContent(coordHeader); } } catch (final Throwable th) { // TODO: handle exception } } }
service.In:/** * */ package org.jboss.ts.contrib.xfire.service; import java.util.Iterator; import org.codehaus.xfire.MessageContext; import org.codehaus.xfire.exchange.InMessage; import org.codehaus.xfire.handler.AbstractHandler; import org.codehaus.xfire.util.stax.JDOMStreamReader; import org.jdom.Element; import com.arjuna.mw.wst.BusinessActivityManagerFactory; import com.arjuna.mw.wst.TransactionManagerFactory; import com.arjuna.mw.wst.TxContext; import com.arjuna.webservices.wsat.AtomicTransactionConstants; import com.arjuna.webservices.wsba.BusinessActivityConstants; import com.arjuna.webservices.wscoor.CoordinationConstants; import com.arjuna.webservices.wscoor.CoordinationContextType; /** * XFireOutHeaderContextProcessor. * @author BDR011 * */ public class XFireInHeaderContextProcessor extends AbstractHandler { /** * @see org.codehaus.xfire.handler.Handler#invoke(org.codehaus.xfire.MessageContext) * @param context * @throws Exception */ public void invoke(MessageContext context) throws Exception { InMessage message = context.getInMessage(); if (null != message && null != message.getHeader()) { Element xfHeader = message.getHeader(); Element coordHeader = getHeaderElement( xfHeader, // the full header CoordinationConstants.WSCOOR_NAMESPACE, // the namespace URI CoordinationConstants.WSCOOR_ELEMENT_COORDINATION_CONTEXT); // the element name JDOMStreamReader in = new JDOMStreamReader(coordHeader); final CoordinationContextType cc = new CoordinationContextType(in); final String coordinationType = cc.getCoordinationType().getValue() ; if (AtomicTransactionConstants.WSAT_PROTOCOL.equals(coordinationType)) { final TxContext txContext = new com.arjuna.mwlabs.wst.at.context.TxContextImple(cc) ; TransactionManagerFactory.transactionManager().resume(txContext) ; } else if (BusinessActivityConstants.WSBA_PROTOCOL_ATOMIC_OUTCOME.equals(coordinationType)) { final TxContext txContext = new com.arjuna.mwlabs.wst.ba.context.TxContextImple(cc); BusinessActivityManagerFactory.businessActivityManager().resume(txContext) ; } else { // TODO: handle unknown coordination type } } } /** * Retrieve the first header matching the uri and name. * @param soapEnvelope The soap envelope containing the header. * @param uri The uri of the header element. * @param name The name of the header element. * @return The header element or null if not found. */ private Element getHeaderElement(final Element messageHeader, final String uri, final String name) { if (messageHeader != null) { final Iterator headerIter = messageHeader.getDescendants() ; while(headerIter.hasNext()) { final Element current = (Element) headerIter.next() ; if (match(name, current.getName()) && match(uri, current.getNamespaceURI())) { return current ; } } } return null ; } /** * Do the two references match? * @param lhs The first reference. * @param rhs The second reference. * @return true if the references are both null or if they are equal. */ private boolean match(final Object lhs, final Object rhs) { if (lhs == null) { return (rhs == null) ; } else { return lhs.equals(rhs) ; } } }
service.Out:/** * */ package org.jboss.ts.contrib.xfire.service; import org.codehaus.xfire.MessageContext; import org.codehaus.xfire.handler.AbstractHandler; import com.arjuna.mw.wst.BusinessActivityManager; import com.arjuna.mw.wst.BusinessActivityManagerFactory; import com.arjuna.mw.wst.TransactionManager; import com.arjuna.mw.wst.TransactionManagerFactory; /** * XFireOutHeaderContextProcessor. * @author BDR011 * */ public class XFireOutHeaderContextProcessor extends AbstractHandler { /** * @see org.codehaus.xfire.handler.Handler#invoke(org.codehaus.xfire.MessageContext) * @param context * @throws Exception */ public void invoke(MessageContext context) throws Exception { suspendTransaction(); } /** * Suspend the current transaction. */ private void suspendTransaction() { try { /* * There should either be an Atomic Transaction *or* a Business Activity * associated with the thread. */ final TransactionManager transactionManager = TransactionManagerFactory.transactionManager() ; final BusinessActivityManager businessActivityManager = BusinessActivityManagerFactory.businessActivityManager() ; if (transactionManager != null) { transactionManager.suspend() ; } if (businessActivityManager != null) { businessActivityManager.suspend() ; } } catch (final Throwable th) { // TODO: handle exception } } }
-
9. Re: XFire
kconner Nov 16, 2006 5:05 AM (in response to ruthbd)Yep, this looks good. The interceptor really is as simple as that :-)
-
10. Re: XFire
bdruth Nov 16, 2006 8:32 AM (in response to ruthbd)Excellent. OK - once I've grokked what Mark wrote in my WS-TX post, I'll hopefully be closer to testing this. I just briefly read through it, but either its too early or I need to read through it a couple more times :)
-Brice