use of io.scalecube.services.methods.MethodInfo in project scalecube by scalecube.
the class ServiceCall method api.
/**
* Create proxy creates a java generic proxy instance by a given service interface.
*
* @param serviceInterface Service Interface type.
* @return newly created service proxy object.
*/
@SuppressWarnings("unchecked")
public <T> T api(Class<T> serviceInterface) {
final ServiceCall serviceCall = this;
final Map<Method, MethodInfo> genericReturnTypes = Reflect.methodsInfo(serviceInterface);
// noinspection unchecked,Convert2Lambda
return (T) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] { serviceInterface }, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] params) {
Optional<Object> check = toStringOrEqualsOrHashCode(method.getName(), serviceInterface, params);
if (check.isPresent()) {
// toString, hashCode was invoked.
return check.get();
}
final MethodInfo methodInfo = genericReturnTypes.get(method);
final Type returnType = methodInfo.parameterizedReturnType();
final boolean isServiceMessage = methodInfo.isReturnTypeServiceMessage();
Object request = methodInfo.requestType() == Void.TYPE ? null : params[0];
switch(methodInfo.communicationMode()) {
case FIRE_AND_FORGET:
return serviceCall.oneWay(toServiceMessage(methodInfo, request));
case REQUEST_RESPONSE:
return serviceCall.requestOne(toServiceMessage(methodInfo, request), returnType).transform(asMono(isServiceMessage));
case REQUEST_STREAM:
return serviceCall.requestMany(toServiceMessage(methodInfo, request), returnType).transform(asFlux(isServiceMessage));
case REQUEST_CHANNEL:
// noinspection rawtypes
return serviceCall.requestBidirectional(Flux.from((Publisher) request).map(data -> toServiceMessage(methodInfo, data)), returnType).transform(asFlux(isServiceMessage));
default:
throw new IllegalArgumentException("Communication mode is not supported: " + method);
}
}
});
}
Aggregations