Async invocation performance improvements

Despite having an asynchronous option, the default CXF client is purely synchronous. Furthermore, the more advanced CXF clients are still synchronous if a custom SSLContext is used. Finally, even when asynchronous, all of the filters, interceptors, readers and writers are run on the calling thread. Performance is better with a simpler implementation which makes use of the PromiseFactory#submit() method and a SyncInvoker.

Signed-off-by: Tim Ward <timothyjward@apache.org>
diff --git a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/cxf/jaxrs/client/PromiseRxInvokerImpl.java b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/cxf/jaxrs/client/PromiseRxInvokerImpl.java
index 7ad5dc3..db0e8df 100644
--- a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/cxf/jaxrs/client/PromiseRxInvokerImpl.java
+++ b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/cxf/jaxrs/client/PromiseRxInvokerImpl.java
@@ -19,51 +19,19 @@
 
 import javax.ws.rs.HttpMethod;
 import javax.ws.rs.client.Entity;
-import javax.ws.rs.client.InvocationCallback;
+import javax.ws.rs.client.SyncInvoker;
 import javax.ws.rs.core.GenericType;
 import javax.ws.rs.core.Response;
 
-import org.apache.cxf.jaxrs.client.WebClient;
 import org.osgi.service.jaxrs.client.PromiseRxInvoker;
-import org.osgi.util.promise.Deferred;
 import org.osgi.util.promise.Promise;
 import org.osgi.util.promise.PromiseFactory;
 
-import java.lang.reflect.Method;
-import java.lang.reflect.Type;
-
 class PromiseRxInvokerImpl implements PromiseRxInvoker {
 
-    private final Method _doInvokeAsyncMethod;
-
-    private static final class DeferredHandler<R> implements InvocationCallback<R> {
-        private final Deferred<R> deferred;
-
-        private DeferredHandler(Deferred<R> deferred) {
-            this.deferred = deferred;
-        }
-
-        @Override
-        public void completed(R response) {
-            deferred.resolve(response);
-        }
-
-        @Override
-        public void failed(Throwable throwable) {
-            deferred.fail(throwable);
-        }
-    }
     public PromiseRxInvokerImpl(
-        WebClient webClient, PromiseFactory promiseFactory) {
-        _webClient = webClient;
-        try {
-            _doInvokeAsyncMethod = WebClient.class.getDeclaredMethod(
-                "doInvokeAsync",
-                String.class, Object.class, Class.class, Type.class, Class.class, Type.class, InvocationCallback.class);
-        } catch (NoSuchMethodException nsme) {
-            throw new RuntimeException(nsme);
-        }
-        _doInvokeAsyncMethod.setAccessible(true);
+        SyncInvoker syncInvoker, PromiseFactory promiseFactory) {
+        _syncInvoker = syncInvoker;
         _promiseFactory = promiseFactory;
     }
 
@@ -104,49 +72,18 @@
 
     @Override
     public <R> Promise<R> method(String s, Class<R> responseType) {
-        Deferred<R> deferred = _promiseFactory.deferred();
-
-        try {
-            _doInvokeAsyncMethod.invoke(
-                _webClient, s, null, null, null, responseType, responseType,
-                new DeferredHandler<R>(deferred));
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-
-        return deferred.getPromise();
+    	return _promiseFactory.submit(() -> _syncInvoker.method(s, responseType));
     }
 
     @Override
     public <R> Promise<R> method(String s, Entity<?> entity, Class<R> responseType) {
-        Deferred<R> deferred = _promiseFactory.deferred();
-
-        try {
-            _doInvokeAsyncMethod.invoke(
-                _webClient, s, entity, null, null, responseType, responseType,
-                new DeferredHandler<R>(deferred));
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-
-        return deferred.getPromise();
+    	return _promiseFactory.submit(() -> _syncInvoker.method(s, entity, responseType));
     }
 
     @Override
     public <R> Promise<R> method(
         String s, Entity<?> entity, GenericType<R> genericType) {
-
-        Deferred<R> deferred = _promiseFactory.deferred();
-
-        try {
-            _doInvokeAsyncMethod.invoke(
-                _webClient, s, entity, null, null, genericType.getRawType(),
-                genericType.getType(), new DeferredHandler<R>(deferred));
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-
-        return deferred.getPromise();
+    	return _promiseFactory.submit(() -> _syncInvoker.method(s, entity, genericType));
     }
 
     @Override
@@ -156,17 +93,7 @@
 
     @Override
     public <R> Promise<R> method(String s, GenericType<R> genericType) {
-        Deferred<R> deferred = _promiseFactory.deferred();
-
-        try {
-            _doInvokeAsyncMethod.invoke(
-                _webClient, s, null, null, null, genericType.getRawType(),
-                genericType.getType(), new DeferredHandler<R>(deferred));
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-
-        return deferred.getPromise();
+    	return _promiseFactory.submit(() -> _syncInvoker.method(s, genericType));
     }
 
     @Override
@@ -235,5 +162,5 @@
     }
 
     private final PromiseFactory _promiseFactory;
-    private final WebClient _webClient;
+    private final SyncInvoker _syncInvoker;
 }
diff --git a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/cxf/jaxrs/client/PromiseRxInvokerProviderImpl.java b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/cxf/jaxrs/client/PromiseRxInvokerProviderImpl.java
index 46e7ade..919ec9f 100644
--- a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/cxf/jaxrs/client/PromiseRxInvokerProviderImpl.java
+++ b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/cxf/jaxrs/client/PromiseRxInvokerProviderImpl.java
@@ -22,7 +22,6 @@
 import javax.ws.rs.client.RxInvokerProvider;
 import javax.ws.rs.client.SyncInvoker;
 
-import org.apache.cxf.jaxrs.client.SyncInvokerImpl;
 import org.osgi.service.jaxrs.client.PromiseRxInvoker;
 import org.osgi.util.promise.PromiseFactory;
 
@@ -48,7 +47,7 @@
                 PromiseFactory.inlineExecutor());
         }
 
-        return new PromiseRxInvokerImpl(((SyncInvokerImpl) syncInvoker).getWebClient(), promiseFactory);
+        return new PromiseRxInvokerImpl(syncInvoker, promiseFactory);
     }
 
 }