diff options
11 files changed, 104 insertions, 15 deletions
diff --git a/examples/bundles/com.mycorp.examples.timeservice.async/META-INF/MANIFEST.MF b/examples/bundles/com.mycorp.examples.timeservice.async/META-INF/MANIFEST.MF index 50340dd18..036dd5f9e 100644 --- a/examples/bundles/com.mycorp.examples.timeservice.async/META-INF/MANIFEST.MF +++ b/examples/bundles/com.mycorp.examples.timeservice.async/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: ECF RS Example Timeservice Async API Bundle-SymbolicName: com.mycorp.examples.timeservice.async Automatic-Module-Name: com.mycorp.examples.timeservice.async -Bundle-Version: 2.0.100.qualifier +Bundle-Version: 2.1.0.qualifier Bundle-Vendor: Eclipse.org - ECF Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Export-Package: com.mycorp.examples.timeservice;version="2.0.0" diff --git a/examples/bundles/com.mycorp.examples.timeservice.async/pom.xml b/examples/bundles/com.mycorp.examples.timeservice.async/pom.xml index b3515c516..ec4245ee7 100644 --- a/examples/bundles/com.mycorp.examples.timeservice.async/pom.xml +++ b/examples/bundles/com.mycorp.examples.timeservice.async/pom.xml @@ -10,6 +10,6 @@ </parent> <groupId>org.eclipse.ecf</groupId> <artifactId>com.mycorp.examples.timeservice.async</artifactId> - <version>2.0.100-SNAPSHOT</version> + <version>2.1.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> </project> diff --git a/examples/bundles/com.mycorp.examples.timeservice.consumer.ds.async/src/com/mycorp/examples/timeservice/consumer/ds/async/TimeServiceComponentAsync.java b/examples/bundles/com.mycorp.examples.timeservice.consumer.ds.async/src/com/mycorp/examples/timeservice/consumer/ds/async/TimeServiceComponentAsync.java index 50b1bf2af..333cf0ef5 100644 --- a/examples/bundles/com.mycorp.examples.timeservice.consumer.ds.async/src/com/mycorp/examples/timeservice/consumer/ds/async/TimeServiceComponentAsync.java +++ b/examples/bundles/com.mycorp.examples.timeservice.consumer.ds.async/src/com/mycorp/examples/timeservice/consumer/ds/async/TimeServiceComponentAsync.java @@ -26,7 +26,12 @@ public class TimeServiceComponentAsync { // Get the CompletableFuture...no blocking here CompletableFuture<Long> cf = timeService.getCurrentTimeAsync(); // print out time when done...no blocking anywhere! - cf.thenAccept((time) -> System.out.println("Remote time is: " + time)); + cf.whenComplete((time, exception) -> { + if (exception != null) + exception.printStackTrace(); + else + System.out.println("Remote time is: " + time); + }); } void unbindTimeService(ITimeServiceAsync timeService) { diff --git a/examples/bundles/com.mycorp.examples.timeservice.consumer.ds/OSGI-INF/com.mycorp.examples.timeservice.consumer.ds.TimeServiceComponent.xml b/examples/bundles/com.mycorp.examples.timeservice.consumer.ds/OSGI-INF/com.mycorp.examples.timeservice.consumer.ds.TimeServiceComponent.xml index b138f9026..1c55cc390 100644 --- a/examples/bundles/com.mycorp.examples.timeservice.consumer.ds/OSGI-INF/com.mycorp.examples.timeservice.consumer.ds.TimeServiceComponent.xml +++ b/examples/bundles/com.mycorp.examples.timeservice.consumer.ds/OSGI-INF/com.mycorp.examples.timeservice.consumer.ds.TimeServiceComponent.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="com.mycorp.examples.timeservice.consumer.ds.TimeServiceComponent"> - <reference bind="bindTimeService" cardinality="1..n" interface="com.mycorp.examples.timeservice.ITimeService" name="TimeService" policy="dynamic" unbind="unbindTimeService"/> + <reference bind="bindTimeService" interface="com.mycorp.examples.timeservice.ITimeService" name="TimeService" unbind="unbindTimeService"/> <implementation class="com.mycorp.examples.timeservice.consumer.ds.TimeServiceComponent"/> </scr:component>
\ No newline at end of file diff --git a/examples/bundles/com.mycorp.examples.timeservice.consumer.ds/src/com/mycorp/examples/timeservice/consumer/ds/TimeServiceComponent.java b/examples/bundles/com.mycorp.examples.timeservice.consumer.ds/src/com/mycorp/examples/timeservice/consumer/ds/TimeServiceComponent.java index 9939bcb03..9fbcbbba7 100644 --- a/examples/bundles/com.mycorp.examples.timeservice.consumer.ds/src/com/mycorp/examples/timeservice/consumer/ds/TimeServiceComponent.java +++ b/examples/bundles/com.mycorp.examples.timeservice.consumer.ds/src/com/mycorp/examples/timeservice/consumer/ds/TimeServiceComponent.java @@ -10,8 +10,6 @@ package com.mycorp.examples.timeservice.consumer.ds; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; -import org.osgi.service.component.annotations.ReferencePolicy; import com.mycorp.examples.timeservice.ITimeService; @@ -19,7 +17,7 @@ import com.mycorp.examples.timeservice.ITimeService; public class TimeServiceComponent { // Called by DS upon ITimeService discovery - @Reference(policy=ReferencePolicy.DYNAMIC, cardinality=ReferenceCardinality.AT_LEAST_ONE) + @Reference void bindTimeService(ITimeService timeService) { System.out.println("Discovered ITimeService via DS. Instance="+timeService); // Call the service and print out result! diff --git a/framework/bundles/org.eclipse.ecf.remoteservice/src/org/eclipse/ecf/remoteservice/AbstractRemoteService.java b/framework/bundles/org.eclipse.ecf.remoteservice/src/org/eclipse/ecf/remoteservice/AbstractRemoteService.java index 4c87e71cc..01437f489 100644 --- a/framework/bundles/org.eclipse.ecf.remoteservice/src/org/eclipse/ecf/remoteservice/AbstractRemoteService.java +++ b/framework/bundles/org.eclipse.ecf.remoteservice/src/org/eclipse/ecf/remoteservice/AbstractRemoteService.java @@ -12,6 +12,7 @@ package org.eclipse.ecf.remoteservice; import java.lang.reflect.*; import java.util.*; import java.util.concurrent.*; +import java.util.concurrent.TimeoutException; import org.eclipse.core.runtime.*; import org.eclipse.ecf.core.jobs.JobsExecutor; import org.eclipse.ecf.core.util.ECFException; @@ -700,6 +701,22 @@ public abstract class AbstractRemoteService extends AbstractAsyncProxyRemoteServ } /** + * @since 8.13 + */ + public Object submitCallable(Callable<Object> callable, long timeout) throws ECFException { + Future<Object> f = getFutureExecutorService(null).submit(callable); + try { + return f.get(timeout, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + throw new ECFException("submitCallable interrupted", e); //$NON-NLS-1$ + } catch (ExecutionException e) { + throw new ECFException("submitCallable interrupted", e.getCause()); //$NON-NLS-1$ + } catch (TimeoutException e) { + throw new ECFException("submitCallable timed out", e); //$NON-NLS-1$ + } + } + + /** * @since 8.2 */ public void dispose() { diff --git a/framework/bundles/org.eclipse.ecf.remoteservice/src/org/eclipse/ecf/remoteservice/client/AbstractRSAClientService.java b/framework/bundles/org.eclipse.ecf.remoteservice/src/org/eclipse/ecf/remoteservice/client/AbstractRSAClientService.java index 39ded4c48..a7bd70f82 100644 --- a/framework/bundles/org.eclipse.ecf.remoteservice/src/org/eclipse/ecf/remoteservice/client/AbstractRSAClientService.java +++ b/framework/bundles/org.eclipse.ecf.remoteservice/src/org/eclipse/ecf/remoteservice/client/AbstractRSAClientService.java @@ -89,8 +89,19 @@ public abstract class AbstractRSAClientService extends AbstractClientService { Object resultObject = invokeObject(proxy, method, args); if (resultObject != null) return resultObject; - if (isAsync(proxy, method, args)) - return invokeAsync(createRemoteCall(proxy, method, getAsyncInvokeMethodName(method), args, getDefaultTimeout())); + try { + // If return is async type (Future, IFuture, CompletableFuture, CompletionStage) + if (isReturnAsync(proxy, method, args)) { + if (isInterfaceAsync(method.getDeclaringClass()) && isMethodAsync(method.getName())) + return invokeAsync(createRemoteCall(proxy, method, getAsyncInvokeMethodName(method), args, getDefaultTimeout())); + // If OSGI Async then invoke method directly + if (isOSGIAsync()) + return invokeReturnAsync(proxy, method, args); + } + } catch (Throwable t) { + handleProxyException("Exception invoking async method on remote service proxy=" + getRemoteServiceID(), t); //$NON-NLS-1$ + } + final String callMethod = getCallMethodNameForProxyInvoke(method, args); final Object[] callParameters = getCallParametersForProxyInvoke(callMethod, method, args); final long callTimeout = getCallTimeoutForProxyInvoke(callMethod, method, args); diff --git a/framework/bundles/org.eclipse.ecf.remoteservice/src/org/eclipse/ecf/remoteservice/provider/RemoteServiceContainerInstantiator.java b/framework/bundles/org.eclipse.ecf.remoteservice/src/org/eclipse/ecf/remoteservice/provider/RemoteServiceContainerInstantiator.java index 46377b378..608b73355 100644 --- a/framework/bundles/org.eclipse.ecf.remoteservice/src/org/eclipse/ecf/remoteservice/provider/RemoteServiceContainerInstantiator.java +++ b/framework/bundles/org.eclipse.ecf.remoteservice/src/org/eclipse/ecf/remoteservice/provider/RemoteServiceContainerInstantiator.java @@ -12,6 +12,7 @@ import java.util.*; import org.eclipse.ecf.core.*; import org.eclipse.ecf.core.provider.BaseContainerInstantiator; import org.eclipse.ecf.core.provider.IRemoteServiceContainerInstantiator; +import org.eclipse.ecf.remoteservice.Constants; import org.eclipse.ecf.remoteservice.IRemoteServiceContainerAdapter; /** @@ -22,7 +23,7 @@ public abstract class RemoteServiceContainerInstantiator extends BaseContainerIn protected static final String[] defaultSupportedAdapterTypes = new String[] {IContainer.class.getName(), IRemoteServiceContainerAdapter.class.getName()}; protected static final Class[][] defaultSupportedParameterTypes = new Class[][] {{Map.class}}; - protected static final String[] defaultSupportedIntents = new String[] {"passByValue", "exactlyOnce", "ordered"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + protected static final String[] defaultSupportedIntents = new String[] {Constants.OSGI_BASIC_INTENT, "passByValue", "exactlyOnce", "ordered"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ public String[] getSupportedAdapterTypes(ContainerTypeDescription description) { return defaultSupportedAdapterTypes; diff --git a/providers/bundles/org.eclipse.ecf.provider.r_osgi/src/org/eclipse/ecf/internal/provider/r_osgi/R_OSGiContainerInstantiator.java b/providers/bundles/org.eclipse.ecf.provider.r_osgi/src/org/eclipse/ecf/internal/provider/r_osgi/R_OSGiContainerInstantiator.java index 2727faa05..23a13b6da 100644 --- a/providers/bundles/org.eclipse.ecf.provider.r_osgi/src/org/eclipse/ecf/internal/provider/r_osgi/R_OSGiContainerInstantiator.java +++ b/providers/bundles/org.eclipse.ecf.provider.r_osgi/src/org/eclipse/ecf/internal/provider/r_osgi/R_OSGiContainerInstantiator.java @@ -46,7 +46,9 @@ public final class R_OSGiContainerInstantiator implements IContainerInstantiator final boolean useHostname = Boolean.valueOf(System.getProperty("org.eclipse.ecf.provider.r_osgi.useHostName", "true")).booleanValue(); //$NON-NLS-1$ //$NON-NLS-2$ private R_OSGiID createROSGiID(ContainerTypeDescription description, Map properties) throws ContainerCreateException { - String idStr = (String) properties.get(ID_PROP); + String idStr = null; + if (properties != null) + idStr = (String) properties.get(ID_PROP); String hostname = null; if (idStr != null) { try { diff --git a/providers/bundles/org.eclipse.ecf.provider.r_osgi/src/org/eclipse/ecf/internal/provider/r_osgi/RemoteServiceImpl.java b/providers/bundles/org.eclipse.ecf.provider.r_osgi/src/org/eclipse/ecf/internal/provider/r_osgi/RemoteServiceImpl.java index 0e05ded28..24ce1cc01 100644 --- a/providers/bundles/org.eclipse.ecf.provider.r_osgi/src/org/eclipse/ecf/internal/provider/r_osgi/RemoteServiceImpl.java +++ b/providers/bundles/org.eclipse.ecf.provider.r_osgi/src/org/eclipse/ecf/internal/provider/r_osgi/RemoteServiceImpl.java @@ -141,8 +141,7 @@ final class RemoteServiceImpl extends AbstractRemoteService { } catch (OperationCanceledException e) { throw new ECFException("callSync cancelled", e); //$NON-NLS-1$ } catch (InterruptedException e) { - // If thread interrupted, then just return null - return null; + throw new ECFException("callSync interrupted ", e); //$NON-NLS-1$ } catch (TimeoutException e) { throw new ECFException("callSync timed out after " + Long.toString(call.getTimeout()) + "ms", new TimeoutException(call.getTimeout())); //$NON-NLS-1$ //$NON-NLS-2$ } diff --git a/providers/bundles/org.eclipse.ecf.provider.remoteservice/src/org/eclipse/ecf/provider/remoteservice/generic/RemoteServiceImpl.java b/providers/bundles/org.eclipse.ecf.provider.remoteservice/src/org/eclipse/ecf/provider/remoteservice/generic/RemoteServiceImpl.java index 7a4de9b3f..8202abdb6 100644 --- a/providers/bundles/org.eclipse.ecf.provider.remoteservice/src/org/eclipse/ecf/provider/remoteservice/generic/RemoteServiceImpl.java +++ b/providers/bundles/org.eclipse.ecf.provider.remoteservice/src/org/eclipse/ecf/provider/remoteservice/generic/RemoteServiceImpl.java @@ -8,8 +8,12 @@ ******************************************************************************/ package org.eclipse.ecf.provider.remoteservice.generic; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicReference; import org.eclipse.ecf.core.util.ECFException; import org.eclipse.ecf.remoteservice.*; +import org.eclipse.ecf.remoteservice.events.IRemoteCallCompleteEvent; +import org.eclipse.ecf.remoteservice.events.IRemoteCallEvent; public class RemoteServiceImpl extends AbstractRemoteService { @@ -39,8 +43,60 @@ public class RemoteServiceImpl extends AbstractRemoteService { * @since 3.0 * @see org.eclipse.ecf.remoteservice.IRemoteService#callAsync(org.eclipse.ecf.remoteservice.IRemoteCall, org.eclipse.ecf.remoteservice.IRemoteCallListener) */ - public void callAsync(IRemoteCall call, IRemoteCallListener listener) { - sharedObject.sendCallRequestWithListener(registration, call, listener); + public void callAsync(final IRemoteCall call, final IRemoteCallListener listener) { + getFutureExecutorService(call).submit(new Runnable() { + public void run() { + final AtomicReference<IRemoteCallEvent> l = new AtomicReference<IRemoteCallEvent>(); + sharedObject.sendCallRequestWithListener(registration, call, new IRemoteCallListener() { + public void handleEvent(IRemoteCallEvent event) { + if (event instanceof IRemoteCallCompleteEvent) { + synchronized (l) { + l.set(event); + l.notify(); + } + } + } + }); + long timeout = call.getTimeout(); + Exception exception = null; + IRemoteCallEvent rce = null; + long sysTimeout = System.currentTimeMillis() + timeout; + synchronized (l) { + try { + while (rce == null && System.currentTimeMillis() < sysTimeout) { + l.wait(timeout / 10); + rce = l.get(); + } + } catch (InterruptedException e) { + exception = e; + } + } + if (rce != null) + listener.handleEvent(rce); + else { + if (exception == null) + exception = new TimeoutException("remote call method=" + call.getMethod() + " timed out after " + timeout + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + final Exception except = exception; + listener.handleEvent(new IRemoteCallCompleteEvent() { + public long getRequestId() { + return 0; + } + + public Object getResponse() { + return null; + } + + public boolean hadException() { + return true; + } + + public Throwable getException() { + return except; + } + }); + } + } + }); } /** |