[jboss-svn-commits] JBossWS SVN: r970 - in branches/tdiesler/trunk/src: main/java/javax/xml/ws main/java/org/jboss/ws/jaxws/client main/java/org/jboss/ws/jaxws/spi test/ant test/java/org/jboss/test/ws/jaxws test/java/org/jboss/test/ws/jaxws/asynchronous test/resources/jaxws test/resources/jaxws/asynchronous test/resources/jaxws/asynchronous/WEB-INF

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri Sep 15 13:04:47 EDT 2006


Author: thomas.diesler at jboss.com
Date: 2006-09-15 13:04:36 -0400 (Fri, 15 Sep 2006)
New Revision: 970

Added:
   branches/tdiesler/trunk/src/main/java/org/jboss/ws/jaxws/client/ResponseImpl.java
   branches/tdiesler/trunk/src/test/java/org/jboss/test/ws/jaxws/asynchronous/
   branches/tdiesler/trunk/src/test/java/org/jboss/test/ws/jaxws/asynchronous/AsynchronousDispatchTestCase.java
   branches/tdiesler/trunk/src/test/java/org/jboss/test/ws/jaxws/asynchronous/TestEndpointBean.java
   branches/tdiesler/trunk/src/test/resources/jaxws/asynchronous/
   branches/tdiesler/trunk/src/test/resources/jaxws/asynchronous/WEB-INF/
   branches/tdiesler/trunk/src/test/resources/jaxws/asynchronous/WEB-INF/web.xml
Modified:
   branches/tdiesler/trunk/src/main/java/javax/xml/ws/AsyncHandler.java
   branches/tdiesler/trunk/src/main/java/org/jboss/ws/jaxws/client/DispatchImpl.java
   branches/tdiesler/trunk/src/main/java/org/jboss/ws/jaxws/spi/ServiceDelegateImpl.java
   branches/tdiesler/trunk/src/test/ant/build-jars-jaxws.xml
Log:
Implement asynchronous dispatch

Modified: branches/tdiesler/trunk/src/main/java/javax/xml/ws/AsyncHandler.java
===================================================================
--- branches/tdiesler/trunk/src/main/java/javax/xml/ws/AsyncHandler.java	2006-09-15 13:01:07 UTC (rev 969)
+++ branches/tdiesler/trunk/src/main/java/javax/xml/ws/AsyncHandler.java	2006-09-15 17:04:36 UTC (rev 970)
@@ -31,6 +31,5 @@
  */
 public interface AsyncHandler<T>
 {
-
    void handleResponse(Response<T> response);
 }
\ No newline at end of file

Modified: branches/tdiesler/trunk/src/main/java/org/jboss/ws/jaxws/client/DispatchImpl.java
===================================================================
--- branches/tdiesler/trunk/src/main/java/org/jboss/ws/jaxws/client/DispatchImpl.java	2006-09-15 13:01:07 UTC (rev 969)
+++ branches/tdiesler/trunk/src/main/java/org/jboss/ws/jaxws/client/DispatchImpl.java	2006-09-15 17:04:36 UTC (rev 970)
@@ -27,6 +27,7 @@
 import java.io.ByteArrayOutputStream;
 import java.io.StringReader;
 import java.util.Map;
+import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Future;
 
 import javax.xml.bind.JAXBContext;
@@ -50,12 +51,11 @@
 import javax.xml.ws.Service.Mode;
 
 import org.jboss.logging.Logger;
-import org.jboss.util.NotImplementedException;
-import org.jboss.ws.utils.DOMWriter;
 import org.jboss.ws.jaxws.core.BindingProviderImpl;
 import org.jboss.ws.metadata.EndpointMetaData;
 import org.jboss.ws.soap.SOAPBodyImpl;
 import org.jboss.ws.soap.SOAPConnectionImpl;
+import org.jboss.ws.utils.DOMWriter;
 
 /**
  * The Dispatch interface provides support for the dynamic invocation of a service endpoint operations. 
@@ -68,25 +68,28 @@
 {
    // provide logging
    private final Logger log = Logger.getLogger(DispatchImpl.class);
-   
+
    private BindingProvider bindingProvider;
    private EndpointMetaData epMetaData;
    private JAXBContext jaxbContext;
+   private ExecutorService executor;
    private Class type;
    private Mode mode;
 
-   public DispatchImpl(EndpointMetaData epMetaData, Class<T> type, Mode mode)
+   public DispatchImpl(ExecutorService executor, EndpointMetaData epMetaData, Class<T> type, Mode mode)
    {
       this.bindingProvider = new BindingProviderImpl(epMetaData.getBindingId());
       this.epMetaData = epMetaData;
+      this.executor = executor;
       this.type = type;
       this.mode = mode;
       initDispatch();
    }
 
-   public DispatchImpl(EndpointMetaData epMetaData, JAXBContext jbc, Mode mode)
+   public DispatchImpl(ExecutorService executor, EndpointMetaData epMetaData, JAXBContext jbc, Mode mode)
    {
       this.epMetaData = epMetaData;
+      this.executor = executor;
       this.type = Object.class;
       this.jaxbContext = jbc;
       this.mode = mode;
@@ -113,12 +116,20 @@
 
    public Response invokeAsync(Object obj)
    {
-      throw new NotImplementedException();
+      ResponseImpl response = new ResponseImpl();
+      Runnable task = new AsyncRunnable(response, null, obj);
+      Future future = executor.submit(task);
+      response.setFuture(future);
+      return response;
    }
 
-   public Future invokeAsync(Object obj, AsyncHandler asynchandler)
+   public Future invokeAsync(Object obj, AsyncHandler handler)
    {
-      throw new NotImplementedException();
+      ResponseImpl response = new ResponseImpl();
+      Runnable task = new AsyncRunnable(response, handler, obj);
+      Future future = executor.submit(task);
+      response.setFuture(future);
+      return response;
    }
 
    public void invokeOneWay(Object obj)
@@ -271,4 +282,28 @@
       }
       return retObj;
    }
+
+   class AsyncRunnable implements Runnable
+   {
+      private ResponseImpl response;
+      private AsyncHandler handler;
+      private Object payload;
+
+      public AsyncRunnable(ResponseImpl response, AsyncHandler handler, Object payload)
+      {
+         this.response = response;
+         this.handler = handler;
+         this.payload = payload;
+      }
+
+      public void run()
+      {
+         Object result = invoke(payload);
+         response.set(result);
+
+         // Call the handler if available
+         if (handler != null)
+            handler.handleResponse(response);
+      }
+   }
 }

Added: branches/tdiesler/trunk/src/main/java/org/jboss/ws/jaxws/client/ResponseImpl.java
===================================================================
--- branches/tdiesler/trunk/src/main/java/org/jboss/ws/jaxws/client/ResponseImpl.java	2006-09-15 13:01:07 UTC (rev 969)
+++ branches/tdiesler/trunk/src/main/java/org/jboss/ws/jaxws/client/ResponseImpl.java	2006-09-15 17:04:36 UTC (rev 970)
@@ -0,0 +1,103 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ws.jaxws.client;
+
+// $Id$
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import javax.xml.ws.Response;
+
+/**
+ * The Response interface provides methods used to obtain the payload and context of a 
+ * message sent in response to an operation invocation.
+ * 
+ * @author Thomas.Diesler at jboss.com
+ * @since 15-Sep-2006
+ */
+public class ResponseImpl implements Response
+{
+   private Future delegate;
+   private Object result;
+   private Map<String, Object> context = new HashMap<String, Object>();
+
+   public Future getFuture()
+   {
+      if (delegate == null)
+         throw new IllegalStateException("Future not available");
+      
+      return delegate;
+   }
+
+   public void setFuture(Future delegate)
+   {
+      this.delegate = delegate;
+   }
+
+   public Map getContext()
+   {
+      return context;
+   }
+   
+   public void set(Object result)
+   {
+      this.result = result;
+   }
+
+   public boolean cancel(boolean mayInterruptIfRunning)
+   {
+      return getFuture().cancel(mayInterruptIfRunning);
+   }
+
+   public Object get() throws InterruptedException, ExecutionException
+   {
+      if (result == null)
+      {
+         getFuture().get();
+      }
+      return result;
+   }
+
+   public Object get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
+   {
+      if (result == null)
+      {
+         getFuture().get(timeout, unit);
+      }
+      return result;
+   }
+
+   public boolean isCancelled()
+   {
+      return getFuture().isCancelled();
+   }
+
+   public boolean isDone()
+   {
+      return getFuture().isDone();
+   }
+}


Property changes on: branches/tdiesler/trunk/src/main/java/org/jboss/ws/jaxws/client/ResponseImpl.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF

Modified: branches/tdiesler/trunk/src/main/java/org/jboss/ws/jaxws/spi/ServiceDelegateImpl.java
===================================================================
--- branches/tdiesler/trunk/src/main/java/org/jboss/ws/jaxws/spi/ServiceDelegateImpl.java	2006-09-15 13:01:07 UTC (rev 969)
+++ branches/tdiesler/trunk/src/main/java/org/jboss/ws/jaxws/spi/ServiceDelegateImpl.java	2006-09-15 17:04:36 UTC (rev 970)
@@ -31,6 +31,8 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 
 import javax.jws.WebService;
 import javax.xml.bind.JAXBContext;
@@ -42,7 +44,6 @@
 import javax.xml.ws.handler.HandlerResolver;
 import javax.xml.ws.spi.ServiceDelegate;
 
-import org.jboss.util.NotImplementedException;
 import org.jboss.ws.Constants;
 import org.jboss.ws.deployment.JAXWSClientMetaDataBuilder;
 import org.jboss.ws.deployment.JSR181ClientMetaDataBuilder;
@@ -74,6 +75,8 @@
    private HashMap<QName, Port> ports = new HashMap<QName,Port>();
    // The handler resolver
    private HandlerResolver handlerResolver = new HandlerResolverImpl();
+   // The executor service
+   private ExecutorService executor;
 
    // A list of annotated ports
    private List<QName> annotatedPorts = new ArrayList<QName>();
@@ -181,16 +184,18 @@
    @Override
    public <T> Dispatch<T> createDispatch(QName portName, Class<T> type, Mode mode)
    {
+      ExecutorService executor = (ExecutorService)getExecutor();
       EndpointMetaData epMetaData = getEndpointMetaData(portName);
-      DispatchImpl dispatch = new DispatchImpl(epMetaData, type, mode);
+      DispatchImpl dispatch = new DispatchImpl(executor, epMetaData, type, mode);
       return dispatch;
    }
 
    @Override
    public Dispatch<Object> createDispatch(QName portName, JAXBContext jbc, Mode mode)
    {
+      ExecutorService executor = (ExecutorService)getExecutor();
       EndpointMetaData epMetaData = getEndpointMetaData(portName);
-      DispatchImpl dispatch = new DispatchImpl(epMetaData, jbc, mode);
+      DispatchImpl dispatch = new DispatchImpl(executor, epMetaData, jbc, mode);
       return dispatch;
    }
 
@@ -251,13 +256,20 @@
    @Override
    public Executor getExecutor()
    {
-      throw new NotImplementedException();
+      if (executor == null)
+      {
+         executor = Executors.newCachedThreadPool();
+      }
+      return executor;
    }
 
    @Override
    public void setExecutor(Executor executor)
    {
-      throw new NotImplementedException();
+      if (!(executor instanceof ExecutorService) == false)
+         throw new IllegalArgumentException("Supported executors must implement " + ExecutorService.class.getName());
+      
+      this.executor = (ExecutorService)executor;
    }
 
    private <T> T createProxy(Class<T> seiClass, EndpointMetaData epMetaData) throws WebServiceException

Modified: branches/tdiesler/trunk/src/test/ant/build-jars-jaxws.xml
===================================================================
--- branches/tdiesler/trunk/src/test/ant/build-jars-jaxws.xml	2006-09-15 13:01:07 UTC (rev 969)
+++ branches/tdiesler/trunk/src/test/ant/build-jars-jaxws.xml	2006-09-15 17:04:36 UTC (rev 970)
@@ -18,6 +18,13 @@
   
   <target name="build-jars" description="Build the deployments.">
     
+    <!-- jaxws-asynchronous -->
+    <war warfile="${build.test.dir}/libs/jaxws-asynchronous.war" webxml="${build.test.dir}/resources/jaxws/asynchronous/WEB-INF/web.xml">
+      <classes dir="${build.test.dir}/classes">
+        <include name="org/jboss/test/ws/jaxws/asynchronous/TestEndpointBean.class"/>
+      </classes>
+    </war>
+    
     <!-- jaxws-binding -->
     <war warfile="${build.test.dir}/libs/jaxws-binding.war" webxml="${build.test.dir}/resources/jaxws/binding/WEB-INF/web.xml">
       <classes dir="${build.test.dir}/classes">

Added: branches/tdiesler/trunk/src/test/java/org/jboss/test/ws/jaxws/asynchronous/AsynchronousDispatchTestCase.java
===================================================================
--- branches/tdiesler/trunk/src/test/java/org/jboss/test/ws/jaxws/asynchronous/AsynchronousDispatchTestCase.java	2006-09-15 13:01:07 UTC (rev 969)
+++ branches/tdiesler/trunk/src/test/java/org/jboss/test/ws/jaxws/asynchronous/AsynchronousDispatchTestCase.java	2006-09-15 17:04:36 UTC (rev 970)
@@ -0,0 +1,113 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.ws.jaxws.asynchronous;
+
+// $Id: $
+
+import java.io.StringReader;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import javax.xml.namespace.QName;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.ws.AsyncHandler;
+import javax.xml.ws.Dispatch;
+import javax.xml.ws.Response;
+import javax.xml.ws.Service;
+import javax.xml.ws.Service.Mode;
+
+import junit.framework.Test;
+
+import org.jboss.test.ws.JBossWSTest;
+import org.jboss.test.ws.JBossWSTestSetup;
+import org.jboss.ws.utils.DOMUtils;
+import org.xml.sax.InputSource;
+
+/**
+ * Test JAXWS asynchrous dispatch
+ *
+ * @author Thomas.Diesler at jboss.org
+ * @since 12-Aug-2006
+ */
+public class AsynchronousDispatchTestCase extends JBossWSTest
+{
+   private String targetNS = "http://org.jboss.ws/jaxws/asynchronous";
+   private String reqPayload = "<ns1:echo xmlns:ns1='" + targetNS + "'><String_1>Hello</String_1></ns1:echo>";
+   private String expPayload = "<ns1:echoResponse xmlns:ns1='" + targetNS + "'><result>Hello</result></ns1:echoResponse>";
+   private Exception handlerException;
+   private boolean asyncHandlerCalled;
+
+   public static Test suite()
+   {
+      return JBossWSTestSetup.newTestSetup(AsynchronousDispatchTestCase.class, "jaxws-asynchronous.war");
+   }
+
+   public void testInvokeAsynch() throws Exception
+   {
+      StreamSource reqObj = new StreamSource(new StringReader(reqPayload));
+      Response response = createDispatch().invokeAsync(reqObj);
+      StreamSource result = (StreamSource)response.get(1000, TimeUnit.MILLISECONDS);
+      InputSource inputSource = new InputSource(result.getReader());
+      assertEquals(DOMUtils.parse(expPayload), DOMUtils.parse(inputSource));
+   }
+
+   public void testInvokeAsynchHandler() throws Exception
+   {
+      AsyncHandler handler = new AsyncHandler()
+      {
+         public void handleResponse(Response response)
+         {
+            try
+            {
+               StreamSource result = (StreamSource)response.get();
+               InputSource inputSource = new InputSource(result.getReader());
+               assertEquals(DOMUtils.parse(expPayload), DOMUtils.parse(inputSource));
+               asyncHandlerCalled = true;
+            }
+            catch (Exception ex)
+            {
+               handlerException = ex;
+            }
+         }
+      };
+      StreamSource reqObj = new StreamSource(new StringReader(reqPayload));
+      Future future = createDispatch().invokeAsync(reqObj, handler);
+      future.get(1000, TimeUnit.MILLISECONDS);
+      
+      if (handlerException != null)
+         throw handlerException;
+      
+      assertTrue("Async handler called", asyncHandlerCalled);
+   }
+
+   private Dispatch createDispatch() throws MalformedURLException
+   {
+      URL wsdlURL = new URL("http://" + getServerHost() + ":8080/jaxws-asynchronous?wsdl");
+      QName serviceName = new QName(targetNS, "TestEndpointService");
+      QName portName = new QName(targetNS, "TestEndpointPort");
+      Service service = Service.create(wsdlURL, serviceName);
+      Dispatch dispatch = service.createDispatch(portName, StreamSource.class, Mode.PAYLOAD);
+      return dispatch;
+   }
+}


Property changes on: branches/tdiesler/trunk/src/test/java/org/jboss/test/ws/jaxws/asynchronous/AsynchronousDispatchTestCase.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF

Added: branches/tdiesler/trunk/src/test/java/org/jboss/test/ws/jaxws/asynchronous/TestEndpointBean.java
===================================================================
--- branches/tdiesler/trunk/src/test/java/org/jboss/test/ws/jaxws/asynchronous/TestEndpointBean.java	2006-09-15 13:01:07 UTC (rev 969)
+++ branches/tdiesler/trunk/src/test/java/org/jboss/test/ws/jaxws/asynchronous/TestEndpointBean.java	2006-09-15 17:04:36 UTC (rev 970)
@@ -0,0 +1,45 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.ws.jaxws.asynchronous;
+
+// $Id: $
+
+import javax.jws.WebMethod;
+import javax.jws.WebService;
+import javax.jws.soap.SOAPBinding;
+import javax.jws.soap.SOAPBinding.Style;
+
+import org.jboss.logging.Logger;
+
+ at WebService(name = "TestEndpoint", targetNamespace = "http://org.jboss.ws/jaxws/asynchronous")
+ at SOAPBinding(style = Style.RPC)
+public class TestEndpointBean
+{
+   private static Logger log = Logger.getLogger(TestEndpointBean.class);
+
+   @WebMethod
+   public String echo(String msg)
+   {
+      log.info("echo: " + msg);
+      return msg;
+   }
+}


Property changes on: branches/tdiesler/trunk/src/test/java/org/jboss/test/ws/jaxws/asynchronous/TestEndpointBean.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF

Added: branches/tdiesler/trunk/src/test/resources/jaxws/asynchronous/WEB-INF/web.xml
===================================================================
--- branches/tdiesler/trunk/src/test/resources/jaxws/asynchronous/WEB-INF/web.xml	2006-09-15 13:01:07 UTC (rev 969)
+++ branches/tdiesler/trunk/src/test/resources/jaxws/asynchronous/WEB-INF/web.xml	2006-09-15 17:04:36 UTC (rev 970)
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
+  version="2.4">
+
+  <servlet>
+    <servlet-name>TestEndpoint</servlet-name>
+    <servlet-class>org.jboss.test.ws.jaxws.asynchronous.TestEndpointBean</servlet-class>
+  </servlet>
+
+  <servlet-mapping>
+    <servlet-name>TestEndpoint</servlet-name>
+    <url-pattern>/*</url-pattern>
+  </servlet-mapping>
+
+</web-app>
+


Property changes on: branches/tdiesler/trunk/src/test/resources/jaxws/asynchronous/WEB-INF/web.xml
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF




More information about the jboss-svn-commits mailing list