Search in sources :

Example 46 with Message

use of io.scalecube.transport.Message 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)

Example 47 with Message

use of io.scalecube.transport.Message in project scalecube by scalecube.

the class TestStreamingService method test_unknown_method.

@Test
public void test_unknown_method() throws InterruptedException {
    Microservices gateway = Microservices.builder().build();
    Microservices node = Microservices.builder().seeds(gateway.cluster().address()).services(new SimpleQuoteService()).build();
    ServiceCall service = gateway.dispatcher().create();
    final CountDownLatch latch1 = new CountDownLatch(1);
    Message scheduled = Messages.builder().request(QuoteService.NAME, "unknonwn").build();
    try {
        service.listen(scheduled);
    } catch (Exception ex) {
        if (ex.getMessage().contains("No reachable member with such service: unknonwn")) {
            latch1.countDown();
        }
    }
    latch1.await(2, TimeUnit.SECONDS);
    assertTrue(latch1.getCount() == 0);
    node.shutdown();
    gateway.shutdown();
}
Also used : ServiceCall(io.scalecube.services.ServiceCall) Message(io.scalecube.transport.Message) CountDownLatch(java.util.concurrent.CountDownLatch) Microservices(io.scalecube.services.Microservices) Test(org.junit.Test) BaseTest(io.scalecube.testlib.BaseTest)

Example 48 with Message

use of io.scalecube.transport.Message in project scalecube by scalecube.

the class SimpleStressTest method test_naive_proxy_stress.

@Test
public void test_naive_proxy_stress() throws InterruptedException, ExecutionException {
    // Create microservices cluster member.
    Microservices provider = Microservices.builder().port(port.incrementAndGet()).services(new GreetingServiceImpl()).metrics(registry).build();
    // Create microservices cluster member.
    Microservices consumer = Microservices.builder().port(port.incrementAndGet()).seeds(provider.cluster().address()).metrics(registry).build();
    reporter.start(10, TimeUnit.SECONDS);
    // Get a proxy to the service api.
    GreetingService service = consumer.proxy().api(// create proxy for GreetingService API
    GreetingService.class).timeout(Duration.ofSeconds(30)).create();
    // Measure
    CountDownLatch countLatch = new CountDownLatch(count);
    long startTime = System.currentTimeMillis();
    for (int i = 0; i < count; i++) {
        CompletableFuture<Message> future = service.greetingMessage(Message.fromData("naive_stress_test"));
        future.whenComplete((success, error) -> {
            if (error == null) {
                countLatch.countDown();
            } else {
                System.out.println("failed: " + error);
                fail("test_naive_stress_not_breaking_the_system failed: " + error);
            }
        });
    }
    System.out.println("Finished sending " + count + " messages in " + (System.currentTimeMillis() - startTime));
    countLatch.await(60, TimeUnit.SECONDS);
    System.out.println("Finished receiving " + (count - countLatch.getCount()) + " messages in " + (System.currentTimeMillis() - startTime));
    System.out.println("Rate: " + ((count - countLatch.getCount()) / ((System.currentTimeMillis() - startTime) / 1000)) + " round-trips/sec");
    reporter.stop();
    assertTrue(countLatch.getCount() == 0);
    provider.shutdown().get();
    consumer.shutdown().get();
}
Also used : Message(io.scalecube.transport.Message) CountDownLatch(java.util.concurrent.CountDownLatch) Microservices(io.scalecube.services.Microservices) Test(org.junit.Test) BaseTest(io.scalecube.testlib.BaseTest)

Example 49 with Message

use of io.scalecube.transport.Message in project scalecube by scalecube.

the class GracefulShutdownTest method test_gracefull_shutdown.

@Test
public void test_gracefull_shutdown() throws InterruptedException {
    // create cluster members with 3 nodes: gateway, node1, node2
    // node 1 and 2 provision GreetingService instance (each).
    Members members = Members.create();
    // get a proxy to the service api.
    ServiceCall service = members.gateway().dispatcher().create();
    // call the service.
    AtomicInteger count = new AtomicInteger(3);
    Message request = Messages.builder().request(GreetingService.class, "greeting").data("joe").build();
    AtomicInteger postShutdown = new AtomicInteger(3);
    // continue with the test while node1 is still active in the cluster
    while (members.gateway().cluster().member(members.node1().cluster().address()).isPresent() || postShutdown.get() >= 0) {
        CompletableFuture<Message> future = service.invoke(request);
        future.whenComplete((result, ex) -> {
            if (ex == null) {
                // print the greeting.
                assertTrue(result.data().equals(" hello to: joe"));
                System.out.println(count.get() + " - Response from node: " + result.sender());
                count.decrementAndGet();
            } else {
                // if one request fails fail the test
                fail();
                // print the greeting.
                System.out.println(ex);
                Exceptions.propagate(ex);
            }
        });
        if (count.get() == 0) {
            // node1 leave the cluster after on 0.
            members.node1().cluster().shutdown();
        }
        // node still answer requests as its only half stopped.
        if (!members.gateway().cluster().member(members.node1().cluster().address()).isPresent()) {
            postShutdown.decrementAndGet();
        }
        sleep(1000);
    }
    members.shutdown();
}
Also used : Message(io.scalecube.transport.Message) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Test(org.junit.Test) BaseTest(io.scalecube.testlib.BaseTest)

Example 50 with Message

use of io.scalecube.transport.Message in project scalecube by scalecube.

the class DispatchingFutureTest method test_dispatching_future.

@Test
public void test_dispatching_future() throws Exception {
    Microservices member = Microservices.builder().build();
    ServiceResponse response = ServiceResponse.correlationId(IdGenerator.generateId());
    Message request = Message.builder().correlationId(response.correlationId()).header(ServiceHeaders.SERVICE_RESPONSE, "").build();
    Field field = Message.class.getDeclaredField("sender");
    field.setAccessible(true);
    field.set(request, member.cluster().address());
    DispatchingFuture dispatcher = DispatchingFuture.from(member.sender(), request);
    dispatcher.complete(new Throwable());
    CountDownLatch latch = new CountDownLatch(1);
    response.future().whenComplete((result, error) -> {
        assertTrue(error != null);
        latch.countDown();
    });
    response.complete(Message.builder().header("exception", "true").data(new Exception()).build());
    latch.await(1, TimeUnit.SECONDS);
    assertTrue(latch.getCount() == 0);
    member.shutdown();
}
Also used : Field(java.lang.reflect.Field) Message(io.scalecube.transport.Message) CountDownLatch(java.util.concurrent.CountDownLatch) Test(org.junit.Test) BaseTest(io.scalecube.testlib.BaseTest)

Aggregations

Message (io.scalecube.transport.Message)51 BaseTest (io.scalecube.testlib.BaseTest)31 Test (org.junit.Test)31 CountDownLatch (java.util.concurrent.CountDownLatch)28 Observable (rx.Observable)10 Member (io.scalecube.cluster.Member)8 Microservices (io.scalecube.services.Microservices)6 TimeUnit (java.util.concurrent.TimeUnit)6 Logger (org.slf4j.Logger)6 LoggerFactory (org.slf4j.LoggerFactory)6 ServiceCall (io.scalecube.services.ServiceCall)5 Collections (java.util.Collections)5 Executors (java.util.concurrent.Executors)5 AtomicReference (java.util.concurrent.atomic.AtomicReference)5 Schedulers (rx.schedulers.Schedulers)5 List (java.util.List)4 Subscription (rx.Subscription)4 PublishSubject (rx.subjects.PublishSubject)4 Subject (rx.subjects.Subject)4 MetricRegistry (com.codahale.metrics.MetricRegistry)3