blob: b5cd74514d558073eec4a6a331228b51b8e5d363 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 Composent, Inc. and others. All rights reserved. This
* program and the accompanying materials are made available under the terms of
* the Eclipse Public License v1.0 which accompanies this distribution, and is
* available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Composent, Inc. - initial API and implementation
******************************************************************************/
package org.eclipse.ecf.remoteservice.client;
import java.lang.reflect.Method;
import org.eclipse.ecf.core.util.ECFException;
import org.eclipse.ecf.remoteservice.IRemoteCall;
import org.eclipse.ecf.remoteservice.RemoteCall;
import org.osgi.framework.ServiceException;
/**
* Abstract client remote service instance. This class should be overridden to implement the abstract
* invokeAsync, and invokeSync methods, which will be called when the proxy created is called by clients.
*
* @since 8.9
*/
public abstract class AbstractRSAClientService extends AbstractClientService {
public static class RSARemoteCall extends RemoteCall {
private final Object proxy;
private final Method reflectMethod;
public RSARemoteCall(Object proxy, Method method, String methodName, Object[] parameters, long timeout) {
super(methodName, parameters, timeout);
this.reflectMethod = method;
this.proxy = proxy;
}
public Method getReflectMethod() {
return reflectMethod;
}
public Object getProxy() {
return proxy;
}
}
/**
* @param call the remote call to invoke
* @param callable the remote callable to invoke
* @return Object result of remote call
* @throws ECFException if invoke fails
*/
@Override
protected Object invokeRemoteCall(IRemoteCall call, IRemoteCallable callable) throws ECFException {
return null;
}
public AbstractRSAClientService(AbstractClientContainer container, RemoteServiceClientRegistration registration) {
super(container, registration);
}
/**
* Invoke a remote call asynchronously. This method should not block and should return either a {@link org.eclipse.equinox.concurrent.future.IFuture}, {@link java.util.concurrent.Future}, or {@link java.util.concurrent.CompletableFuture}
* or a
* CompletableFuture based upon the return type defined in the asynchronous service interface.
*
* @param remoteCall the RSARemoteCall to use to make the asynchronous remote call. Will not be <code>null</code>.
* @return Object. Should return a non-null instance of {@link org.eclipse.equinox.concurrent.future.IFuture}, {@link java.util.concurrent.Future}, or {@link java.util.concurrent.CompletableFuture}
* @throws ECFException if async cannot be invoked
*/
protected abstract Object invokeAsync(RSARemoteCall remoteCall) throws ECFException;
/**
* Invoke a remote call synchronously. This method should block until a value may be returned, or the remote
* call has failed or timed out.
*
* @param remoteCall the RSARemoteCall to synchronously invoke. Will not be <code>null</code>.
* @return the result (of appropriate type)
* @throws ECFException if some exception occurred during invocation
*/
protected abstract Object invokeSync(RSARemoteCall remoteCall) throws ECFException;
protected RSARemoteCall createRemoteCall(Object proxy, Method method, String methodName, Object[] parameters, long timeout) {
return new RSARemoteCall(proxy, method, methodName, parameters, timeout);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
Object resultObject = invokeObject(proxy, method, args);
if (resultObject != null)
return resultObject;
if (isAsync(proxy, method, args))
return invokeAsync(createRemoteCall(proxy, method, getAsyncInvokeMethodName(method), args, IRemoteCall.DEFAULT_TIMEOUT));
final String callMethod = getCallMethodNameForProxyInvoke(method, args);
final Object[] callParameters = getCallParametersForProxyInvoke(callMethod, method, args);
final long callTimeout = getCallTimeoutForProxyInvoke(callMethod, method, args);
return invokeSync(createRemoteCall(proxy, method, callMethod, callParameters, callTimeout));
} catch (Throwable t) {
if (t instanceof ServiceException)
throw t;
// rethrow as service exception
throw new ServiceException("Service exception on remote service proxy rsid=" + getRemoteServiceID(), ServiceException.REMOTE, t); //$NON-NLS-1$
}
}
}