You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicemix.apache.org by gn...@apache.org on 2006/12/27 13:09:59 UTC

svn commit: r490484 - in /incubator/servicemix/trunk/deployables/serviceengines/servicemix-jsr181/src/main/java/org/apache/servicemix/jsr181/xfire: JbiChannel.java JbiProxy.java JbiProxyFactoryBean.java

Author: gnodet
Date: Wed Dec 27 04:09:58 2006
New Revision: 490484

URL: http://svn.apache.org/viewvc?view=rev&rev=490484
Log:
SM-794: jsr181 proxy does not throw faults correctly when used in jaxws mode

Modified:
    incubator/servicemix/trunk/deployables/serviceengines/servicemix-jsr181/src/main/java/org/apache/servicemix/jsr181/xfire/JbiChannel.java
    incubator/servicemix/trunk/deployables/serviceengines/servicemix-jsr181/src/main/java/org/apache/servicemix/jsr181/xfire/JbiProxy.java
    incubator/servicemix/trunk/deployables/serviceengines/servicemix-jsr181/src/main/java/org/apache/servicemix/jsr181/xfire/JbiProxyFactoryBean.java

Modified: incubator/servicemix/trunk/deployables/serviceengines/servicemix-jsr181/src/main/java/org/apache/servicemix/jsr181/xfire/JbiChannel.java
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/deployables/serviceengines/servicemix-jsr181/src/main/java/org/apache/servicemix/jsr181/xfire/JbiChannel.java?view=diff&rev=490484&r1=490483&r2=490484
==============================================================================
--- incubator/servicemix/trunk/deployables/serviceengines/servicemix-jsr181/src/main/java/org/apache/servicemix/jsr181/xfire/JbiChannel.java (original)
+++ incubator/servicemix/trunk/deployables/serviceengines/servicemix-jsr181/src/main/java/org/apache/servicemix/jsr181/xfire/JbiChannel.java Wed Dec 27 04:09:58 2006
@@ -35,6 +35,7 @@
 import javax.xml.transform.stream.StreamSource;
 
 import org.apache.servicemix.jbi.jaxp.StAXSourceTransformer;
+import org.apache.servicemix.jbi.jaxp.StringSource;
 import org.codehaus.xfire.MessageContext;
 import org.codehaus.xfire.XFireException;
 import org.codehaus.xfire.exchange.InMessage;
@@ -44,6 +45,8 @@
 import org.codehaus.xfire.soap.AbstractSoapBinding;
 import org.codehaus.xfire.transport.AbstractChannel;
 import org.codehaus.xfire.transport.Channel;
+import org.jdom.Element;
+import org.jdom.transform.JDOMResult;
 
 /**
  * Jbi channel, only support local invocations. 
@@ -104,7 +107,14 @@
                             throw new XFireFault("Unkown Error", XFireFault.RECEIVER);
                         }
                     } else if (me.getFault() != null){
-                        throw new XFireFault(sourceTransformer.contentToString(me.getFault()), XFireFault.RECEIVER);
+                        JDOMResult result = new JDOMResult();
+                        String str = sourceTransformer.contentToString(me.getFault());
+                        sourceTransformer.toResult(new StringSource(str), result);
+                        Element e = result.getDocument().getRootElement();
+                        e = (Element) e.clone();
+                        XFireFault xfireFault = new XFireFault(str, XFireFault.RECEIVER);
+                        xfireFault.getDetail().addContent(e);
+                        throw xfireFault;
                     }
                     Source outSrc = me.getOutMessage().getContent();
 
@@ -116,8 +126,8 @@
                 } else {
                     // TODO
                 }
-                
-                
+            } catch (XFireException e) {
+                throw e;
             } catch (Exception e) {
                 throw new XFireException("Error sending jbi exchange", e);
             }

Modified: incubator/servicemix/trunk/deployables/serviceengines/servicemix-jsr181/src/main/java/org/apache/servicemix/jsr181/xfire/JbiProxy.java
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/deployables/serviceengines/servicemix-jsr181/src/main/java/org/apache/servicemix/jsr181/xfire/JbiProxy.java?view=diff&rev=490484&r1=490483&r2=490484
==============================================================================
--- incubator/servicemix/trunk/deployables/serviceengines/servicemix-jsr181/src/main/java/org/apache/servicemix/jsr181/xfire/JbiProxy.java (original)
+++ incubator/servicemix/trunk/deployables/serviceengines/servicemix-jsr181/src/main/java/org/apache/servicemix/jsr181/xfire/JbiProxy.java Wed Dec 27 04:09:58 2006
@@ -16,7 +16,12 @@
  */
 package org.apache.servicemix.jsr181.xfire;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import javax.jbi.JBIException;
@@ -25,20 +30,35 @@
 import javax.wsdl.Definition;
 import javax.wsdl.factory.WSDLFactory;
 import javax.wsdl.xml.WSDLReader;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
 import javax.xml.namespace.QName;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.ws.WebFault;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.servicemix.jsr181.xfire.ServiceFactoryHelper.FixedJAXWSServiceFactory;
 import org.codehaus.xfire.XFire;
 import org.codehaus.xfire.annotations.AnnotationServiceFactory;
 import org.codehaus.xfire.client.Client;
 import org.codehaus.xfire.client.XFireProxyFactory;
+import org.codehaus.xfire.fault.XFireFault;
+import org.codehaus.xfire.service.OperationInfo;
 import org.codehaus.xfire.service.Service;
 import org.codehaus.xfire.service.ServiceFactory;
+import org.codehaus.xfire.util.jdom.StaxSerializer;
+import org.jdom.Element;
 import org.w3c.dom.Document;
 
 import com.ibm.wsdl.Constants;
 
 public class JbiProxy {
     
+    private static final Log logger = LogFactory.getLog(JbiProxyFactoryBean.class);
+
     protected XFire xfire;
     protected ComponentContext context;
     protected QName interfaceName;
@@ -89,7 +109,12 @@
             props.put(AnnotationServiceFactory.ALLOW_INTERFACE, Boolean.TRUE);
             ServiceFactory factory = ServiceFactoryHelper.findServiceFactory(xfire, serviceClass, null, null);
             Service service = factory.create(serviceClass, props);
-            JBIClient client = new JBIClient(xfire, service);
+            JBIClient client;
+            if (factory instanceof FixedJAXWSServiceFactory) {
+                client = new JAXWSJBIClient(xfire, service);
+            } else {
+                client = new JBIClient(xfire, service);
+            }
             if (interfaceName != null) {
                 client.getService().setProperty(JbiChannel.JBI_INTERFACE_NAME, interfaceName);
             }
@@ -163,6 +188,76 @@
                   null);
             setXFire(xfire);
         }
+    }
+    
+    protected static class JAXWSJBIClient extends JBIClient {
+        public JAXWSJBIClient(XFire xfire, Service service) throws Exception {
+            super(xfire, service);
+        }
+        public Object[] invoke(OperationInfo op, Object[] params) throws Exception {
+            try {
+                return super.invoke(op, params);
+            } catch (Exception e) {
+                throw translateException(op.getMethod(), e);
+            }
+        }
+        protected Exception translateException(Method method, Exception t) {
+            if (t instanceof XFireFault == false) {
+                logger.debug("Exception is not an XFireFault");
+                return t;
+            }
+            XFireFault xfireFault = (XFireFault) t;
+            if (!xfireFault.hasDetails()) {
+                logger.debug("XFireFault has no details");
+                return t;
+            }
+            // Get first child element of <detail/>
+            List details = xfireFault.getDetail().getContent();
+            Element detail = null;
+            for (Object o : details) {
+                if (o instanceof Element) {
+                    detail = (Element) o;
+                    break;
+                }
+            }
+            if (detail == null) {
+                logger.debug("XFireFault has no element in <detail/>");
+                return t;
+            }
+            QName qname = new QName(detail.getNamespaceURI(),
+                                    detail.getName());
+            Class<?>[] exceptions = method.getExceptionTypes();
+            for (int i = 0; i < exceptions.length; i++) {
+                logger.debug("Checking exception: " + exceptions[i]);
+                WebFault wf = exceptions[i].getAnnotation(WebFault.class);
+                if (wf == null) {
+                    logger.debug("No WebFault annotation");
+                    continue;
+                }
+                QName exceptionName = new QName(wf.targetNamespace(), wf.name());
+                if (exceptionName.equals(qname)) {
+                    try {
+                        Method mth = exceptions[i].getMethod("getFaultInfo");
+                        Class<?> infoClass = mth.getReturnType();
+                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                        XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(baos);
+                        new StaxSerializer().writeElement(detail, writer);
+                        writer.close();
+                        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+                        JAXBElement<?> obj = JAXBContext.newInstance(infoClass).createUnmarshaller().unmarshal(new StreamSource(bais), infoClass);
+                        Constructor<?> cst = exceptions[i].getConstructor(String.class, infoClass);
+                        Exception e = (Exception) cst.newInstance(xfireFault.toString(), obj.getValue());
+                        return e;
+                    } catch (Throwable e) {
+                        logger.debug("Error: " + e);
+                    }
+                } else {
+                    logger.debug("QName mismatch: element: " + qname + ", exception: " + exceptionName);
+                }
+            }
+            return t;
+        }
         
     }
+    
 }

Modified: incubator/servicemix/trunk/deployables/serviceengines/servicemix-jsr181/src/main/java/org/apache/servicemix/jsr181/xfire/JbiProxyFactoryBean.java
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/deployables/serviceengines/servicemix-jsr181/src/main/java/org/apache/servicemix/jsr181/xfire/JbiProxyFactoryBean.java?view=diff&rev=490484&r1=490483&r2=490484
==============================================================================
--- incubator/servicemix/trunk/deployables/serviceengines/servicemix-jsr181/src/main/java/org/apache/servicemix/jsr181/xfire/JbiProxyFactoryBean.java (original)
+++ incubator/servicemix/trunk/deployables/serviceengines/servicemix-jsr181/src/main/java/org/apache/servicemix/jsr181/xfire/JbiProxyFactoryBean.java Wed Dec 27 04:09:58 2006
@@ -20,19 +20,20 @@
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 
-import javax.jbi.JBIException;
 import javax.jbi.component.ComponentContext;
 import javax.naming.InitialContext;
 import javax.xml.namespace.QName;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.apache.servicemix.client.ClientFactory;
-import org.apache.servicemix.client.DefaultServiceMixClient;
 import org.apache.servicemix.client.ServiceMixClient;
-import org.apache.servicemix.client.ServiceMixClientFacade;
 import org.apache.servicemix.jbi.container.JBIContainer;
 import org.apache.servicemix.jsr181.Jsr181Component;
 import org.codehaus.xfire.XFire;
+import org.springframework.beans.factory.DisposableBean;
 import org.springframework.beans.factory.FactoryBean;
+import org.springframework.beans.factory.InitializingBean;
 
 
 /**
@@ -43,7 +44,9 @@
  *                  description="A jsr181 proxy"
  * 
  */
-public class JbiProxyFactoryBean implements FactoryBean {
+public class JbiProxyFactoryBean implements FactoryBean, InitializingBean, DisposableBean {
+    
+    private static final Log logger = LogFactory.getLog(JbiProxyFactoryBean.class);
 
     private String name = ClientFactory.DEFAULT_JNDI_NAME;
     private JBIContainer container;
@@ -56,6 +59,8 @@
     private QName interfaceName;
     private String endpoint;
     
+    private ServiceMixClient client;
+    
     public Object getObject() throws Exception {
         if( proxy == null ) {
             proxy = createProxy();
@@ -64,14 +69,12 @@
     }
 
     private Object createProxy() throws Exception {
-        
         return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{type}, new InvocationHandler(){
             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                 InvocationHandler next = getJBIInvocationHandler();
                 return next.invoke(proxy, method, args);
             }
         });
-        
     }
     
     synchronized private InvocationHandler getJBIInvocationHandler() throws Exception {
@@ -94,19 +97,13 @@
     protected ComponentContext getInternalContext() throws Exception {
         if (context == null) {
             if (factory == null) {
-                if (context != null) {
-                    factory = new ClientFactory() {
-                        public ServiceMixClient createClient() throws JBIException {
-                            return new ServiceMixClientFacade(context);
-                        }
-                    };
-                } else if (container != null) {
+                if (container != null) {
                     factory = container.getClientFactory();
                 } else {
                     factory = (ClientFactory) new InitialContext().lookup(name);
                 }
             }
-            DefaultServiceMixClient client = new DefaultServiceMixClient(container);
+            client = factory.createClient();
             context = client.getContext();
         }
         return context;
@@ -198,6 +195,19 @@
      */
     public void setName(String name) {
         this.name = name;
+    }
+
+    public void afterPropertiesSet() throws Exception {
+        if (type == null) {
+            throw new IllegalArgumentException("type must be set");
+        }
+    }
+
+    public void destroy() throws Exception {
+        if (client != null) {
+            client.close();
+            client = null;
+        }
     }
 
 }