Search in sources :

Example 1 with Metrics

use of io.scalecube.services.metrics.Metrics in project scalecube by scalecube.

the class ServiceProxyFactory method createProxy.

/**
 * createProxy creates a java generic proxy instance by a given service interface.
 *
 * @param <T> service interface type
 * @param serviceInterface the service interface, api, of the service.
 * @param routerType the type of routing method class to be used.
 * @param metrics optional performance metrics.
 * @return newly created service proxy object.
 */
public <T> T createProxy(Class<T> serviceInterface, final Class<? extends Router> routerType, Duration timeout, Metrics metrics) {
    ServiceDefinition serviceDefinition = serviceRegistry.registerInterface(serviceInterface);
    dispatcher = microservices.dispatcher().router(routerType).timeout(timeout).create();
    return Reflection.newProxy(serviceInterface, new InvocationHandler() {

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Metrics.mark(serviceInterface, metrics, method, "request");
            Object data = method.getParameterCount() != 0 ? args[0] : null;
            final Message reqMsg = getRequestMessage(serviceDefinition, method, data);
            if (method.getReturnType().equals(Observable.class)) {
                if (Reflect.parameterizedReturnType(method).equals(Message.class)) {
                    return dispatcher.listen(reqMsg);
                } else {
                    return dispatcher.listen(reqMsg).map(message -> message.data());
                }
            } else {
                return toReturnValue(method, dispatcher.invoke(reqMsg));
            }
        }

        private Message getRequestMessage(ServiceDefinition serviceDefinition, Method method, Object data) {
            if (data instanceof Message) {
                return Messages.builder().request(serviceDefinition.serviceName(), method.getName()).data(((Message) data).data()).build();
            } else {
                return Messages.builder().request(serviceDefinition.serviceName(), method.getName()).data(data).build();
            }
        }

        private CompletableFuture<T> toReturnValue(final Method method, final CompletableFuture<Message> reuslt) {
            final CompletableFuture<T> future = new CompletableFuture<>();
            if (method.getReturnType().equals(Void.TYPE)) {
                return (CompletableFuture<T>) CompletableFuture.completedFuture(Void.TYPE);
            } else if (method.getReturnType().equals(CompletableFuture.class)) {
                reuslt.whenComplete((value, ex) -> {
                    if (ex == null) {
                        Metrics.mark(serviceInterface, metrics, method, "response");
                        if (!Reflect.parameterizedReturnType(method).equals(Message.class)) {
                            future.complete(value.data());
                        } else {
                            future.complete((T) value);
                        }
                    } else {
                        Metrics.mark(serviceInterface, metrics, method, "error");
                        LOGGER.error("return value is exception: {}", ex);
                        future.completeExceptionally(ex);
                    }
                });
                return future;
            } else {
                LOGGER.error("return value is not supported type.");
                future.completeExceptionally(new UnsupportedOperationException());
            }
            return future;
        }
    });
}
Also used : Metrics(io.scalecube.services.metrics.Metrics) Logger(org.slf4j.Logger) Duration(java.time.Duration) LoggerFactory(org.slf4j.LoggerFactory) Reflection(com.google.common.reflect.Reflection) CompletableFuture(java.util.concurrent.CompletableFuture) Message(io.scalecube.transport.Message) InvocationHandler(java.lang.reflect.InvocationHandler) Router(io.scalecube.services.routing.Router) Method(java.lang.reflect.Method) Observable(rx.Observable) Message(io.scalecube.transport.Message) Method(java.lang.reflect.Method) InvocationHandler(java.lang.reflect.InvocationHandler) Observable(rx.Observable) CompletableFuture(java.util.concurrent.CompletableFuture)

Aggregations

Reflection (com.google.common.reflect.Reflection)1 Metrics (io.scalecube.services.metrics.Metrics)1 Router (io.scalecube.services.routing.Router)1 Message (io.scalecube.transport.Message)1 InvocationHandler (java.lang.reflect.InvocationHandler)1 Method (java.lang.reflect.Method)1 Duration (java.time.Duration)1 CompletableFuture (java.util.concurrent.CompletableFuture)1 Logger (org.slf4j.Logger)1 LoggerFactory (org.slf4j.LoggerFactory)1 Observable (rx.Observable)1