D10086 - Micro, Future with Utility X

This chapter we still stay at the first Rpc example, but we switch our programming style with Utility X to let your rpc code more simple.

1. Services

This demo services should be as following:

Here are three projects in current demo:

Http Port Ipc Port Ipc Service Name Project Role
6100 up-athena Api Gateway
6201 up-atlas Common Service
6401 6411 ipc-coeus up-coeus Coordinator A

2. Source Code

2.1. FutureApi ( service: up-atlas )

package up.god.micro.rpc;

import io.vertx.up.annotations.Address;
import io.vertx.up.annotations.EndPoint;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;

@EndPoint
@Path("/api")
public interface FutureApi {
    @Path("ipc/future/{name}")
    @GET
    @Address("ZERO://RPC/SECOND")
    String sayHello(@PathParam("name") String name);
}

2.2. FutureWorker ( service: up-atlas )

package up.god.micro.rpc;

import io.vertx.core.Future;
import io.vertx.core.json.JsonObject;
import io.vertx.up.unity.Ux;
import io.vertx.up.annotations.Address;
import io.vertx.up.annotations.Queue;
import io.vertx.up.commune.Envelop;

@Queue
public class FutureWorker {
    @Address("ZERO://RPC/SECOND")
    public Future<JsonObject> sayHello(final Envelop envelop) {
        final String name = Ux.getString(envelop);
        final JsonObject params = new JsonObject().put("name", name);
        return Ux.thenRpc("ipc-coeus", "RPC://SAY/FUTURE", params);
    }
}

2.3. HelloInsider ( service: up-coeus )

Here we list completed rpc services so that developers could compare different styles in rpc service

package up.god.ipc;

import io.vertx.core.Future;
import io.vertx.core.json.JsonObject;
import io.vertx.up.unity.Uson;
import io.vertx.up.annotations.Ipc;
import io.vertx.up.commune.Envelop;

public class HelloInsider {

    @Ipc("RPC://SAY/HELLO")
    public Envelop sayHello(final Envelop envelop) {
        final JsonObject data = envelop.data();
        System.out.println(data);
        return Envelop.success(data);
    }
    // New added method to this service.
    @Ipc("RPC://SAY/FUTURE")
    public Future<JsonObject> sayFuture(final Envelop envelop) {
        final JsonObject data = envelop.data();
        // You can use Jooq here directly 
        return Uson.create(data).toFuture();
    }
}

3. Testing

Then you can start three services and testing:

URL : http://localhost:6100/api/ipc/future/huan.huan

Method : GET

Response :

{
    "data": {
        "name": "huan.huan"
    }
}

4. Console

4.1. Start Up Console

Here you should focus on some specific logs in console output when services are started up.

common service: up-atlas

    [ Up Micro ] <Application Name> = "zero-istio",
    [ Up Micro ] Configuration Path = /zero/zero-istio/endpoint/routes/up-atlas:10.0.0.6:6201, 
    [ Up Micro ] Service Name = up-atlas,
    [ Up Micro ] EndPoint = http://10.0.0.6:6201
    [ Up Micro ] Route Uris = 
    [ Up Micro ]     /api/ipc/future/:name
    [ Up Micro ]     /api/rpc/:name
    [ Up Micro ] √ Successfully to registered Routes, wait for discovery......SUCCESS √

coordinator: up-coeus

    [ Up Rpc   ] <Application Name> = "zero-istio",
    [ Up Rpc   ] Configuration Rpc Point = /zero/zero-istio/ipc/routes/ipc-coeus:10.0.0.6:6411, 
    [ Up Rpc   ] Service Name = ipc-coeus,
    [ Up Rpc   ] Ipc Channel = grpc://10.0.0.6:6411
    [ Up Rpc   ] Ipc Address = 
    [ Up Rpc √ ]     RPC://SAY/FUTURE
    [ Up Rpc √ ]     RPC://SAY/HELLO
    [ Up Rpc   ] √ Successfully to registered IPCs, wait for community......SUCCESS √

4.2. Request Flow

coordinator: up-coeus

[ ZERO ] --> ( Terminator ) found, will provide response. ......
......
[ ZERO ] Current flow is Future<T>, return type = class io.vertx.core.impl.SucceededFuture

common service: up-atlas

[ ZERO ] ( Rpc Client ) Build channel ( host = 10.0.0.6, port = 6411, hashCode = 461512011 )
[ ZERO ] ( Rpc Client ) Final Traffic Data will be IpcData......
[ ZERO ] ( Rpc Client ) Response Json data is {"name":"huan.huan"}
[ ZERO ] ( Rpc -> thenRpc ) Client = 1864168592, Ipc ( ipc-coeus,RPC://SAY/FUTURE )......

5. Summary

This chapter programming style is recommend by zero system because all the workflow will be async. Here from the console output message the developers could know rpc details. Another thing here that developers should know:

In this example we could see our node up-coeus is Coordinator, but the message output show that:

[ ZERO ] --> ( Terminator ) found, will provide response. ......

Actually here up-coeus role is Terminator instead of Coordinator because this node has not forward service node.