Author: dblevins
Date: Thu Jan 21 22:49:29 2010
New Revision: 901906

URL: http://svn.apache.org/viewvc?rev=901906&view=rev
Log:
Patch from Luis Fernando Planella Gonzalez, OPENEJB-1165:  
javax.ejb.Asynchronous
Partial support.  Nice little Async method invoker.

Added:
    
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/AsynchronousRunner.java
   (with props)
    
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/AsynchronousRunnerTest.java
   (with props)

Added: 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/AsynchronousRunner.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/AsynchronousRunner.java?rev=901906&view=auto
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/AsynchronousRunner.java
 (added)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/AsynchronousRunner.java
 Thu Jan 21 22:49:29 2010
@@ -0,0 +1,94 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.util;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Utility class used to invoke methods asynchronously, using a given 
{...@link Executor}.
+ * For debugging purposes, a system property named 
openejb.asynchronousRunner.sleepTime
+ * may be set to a long value, indicating a time the execution will wait 
before actually
+ * running the method
+ * @author Apache Software Foundation
+ */
+public class AsynchronousRunner {
+
+    /**
+     * A {...@link Callable} implementation which just delegates the execution 
using 
+     * {...@link Method#invoke(Object, Object...)}
+     * @author luis
+     */
+    private class MethodInvoker implements Callable<Object> {
+        private Object object;
+        private Method method;
+        private Object[] arguments;
+
+        public MethodInvoker(Object object, Method method, Object[] arguments) 
{
+            this.object = object;
+            this.method = method;
+            this.arguments = arguments;
+        }
+
+        public Object call() throws Exception {
+            Thread.sleep(sleepTime);
+            return method.invoke(object, arguments);
+        }
+    }
+    
+    public static void main(String[] args) throws Exception {
+        Collection<String> object = new ArrayList<String>();
+        Method method = object.getClass().getMethod("add", Object.class);
+        Object[] arguments = {"Item 1"};
+        
+        AsynchronousRunner asyncRunner = new 
AsynchronousRunner(Executors.newCachedThreadPool());
+        Future<Object> future = asyncRunner.runAsync(object, method, 
arguments);
+        future.cancel(true);
+        Object result = future.get(5001, TimeUnit.MILLISECONDS);
+        System.out.println(result);
+    }
+
+    private Executor executor;
+    private long sleepTime;
+
+    public AsynchronousRunner(Executor executor) {
+        this.executor = executor;
+        sleepTime = Long.getLong("openejb.asynchronousRunnerSleep", 0);
+    }
+
+    /**
+     * Performs the given method invocation asynchronously
+     * @param object The object which will have the method invoked
+     * @param method The method to be invoked
+     * @param arguments The invocation arguments
+     * @return A {...@link Future} containing the method return value
+     */
+    public Future<Object> runAsync(Object object, Method method, Object... 
arguments) {
+        Callable<Object> callable = new MethodInvoker(object, method, 
arguments);
+        FutureTask<Object> futureTask = new FutureTask<Object>(callable);
+        executor.execute(futureTask);
+        return futureTask;
+    }
+
+}

Propchange: 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/AsynchronousRunner.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/AsynchronousRunnerTest.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/AsynchronousRunnerTest.java?rev=901906&view=auto
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/AsynchronousRunnerTest.java
 (added)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/AsynchronousRunnerTest.java
 Thu Jan 21 22:49:29 2010
@@ -0,0 +1,114 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.util;
+
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import junit.framework.TestCase;
+
+public class AsynchronousRunnerTest extends TestCase {
+
+    /**
+     * A delayed get, sleeping until the result is complete
+     */
+    public void testDelayedGet() throws Exception {
+        AsynchronousRunner asyncRunner = instantiate(2000);
+        Future<Object> future = asyncRunner.runAsync(object(), method(), 
arguments());
+        assertFalse(future.isDone());
+        Thread.sleep(2500);
+        assertTrue(future.isDone());
+        assertEquals(expected(), future.get());
+    }
+    
+    /**
+     * A regular get, waiting for result to be complete
+     */
+    public void testGet() throws Exception {
+        AsynchronousRunner asyncRunner = instantiate();
+        Future<Object> future = asyncRunner.runAsync(object(), method(), 
arguments());
+        assertEquals(expected(), future.get());
+    }
+    
+    /**
+     * A get with max timeout
+     */
+    public void testTimedGet() throws Exception {
+        AsynchronousRunner asyncRunner = instantiate(2000);
+        Future<Object> future = asyncRunner.runAsync(object(), method(), 
arguments());
+        try {
+            future.get(1, TimeUnit.SECONDS);
+            fail();
+        } catch (TimeoutException e) {
+            //Ok
+        }
+        Thread.sleep(1500);
+        assertTrue(future.isDone());
+        assertEquals(expected(), future.get());
+    }
+    
+    /**
+     * Tests the cancel method
+     */
+    public void testCancel() throws Exception {
+        AsynchronousRunner asyncRunner = instantiate(2000);
+        Future<Object> future = asyncRunner.runAsync(object(), method(), 
arguments());
+        future.cancel(true);
+        assertTrue(future.isCancelled());
+        try {
+            future.get();
+        } catch (CancellationException e) {
+            //Ok
+        }
+    }
+    
+    private Object[] arguments() {
+        return new Object[] {BigDecimal.ONE};
+    }
+    
+    private BigDecimal expected() {
+        return new BigDecimal(11);
+    }
+    
+    private AsynchronousRunner instantiate() {
+        return instantiate(0);
+    }
+
+    private AsynchronousRunner instantiate(long timeout) {
+        System.setProperty("openejb.asynchronousRunnerSleep", "" + timeout);
+        return new AsynchronousRunner(Executors.newCachedThreadPool());
+    }
+    
+    private Method method() {
+        try {
+            return BigDecimal.class.getMethod("add", BigDecimal.class);
+        } catch (Exception e) {
+            throw new IllegalStateException(e);
+        }
+    }
+    
+    private Object object() {
+        return BigDecimal.TEN;
+    }
+
+}
+

Propchange: 
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/AsynchronousRunnerTest.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to