Guice is really easy to use DI framework. This post is not about explaining how it works.

Vert.x is also easy (unless you have more then 10 Verticles sending 5k/s messages to each other).

Simple technologies should play well together. So it is with Guice and Vert.x.

WimbledonVerticle - better than MyVerticle

Soon Roger Federer and Novak Djokovic will play for Wimbledon Championship. Let’s use them in small application, which will handles HTTP GET request and returns name of tournament winner based on their Karma.

Below, WimbledonVerticle code snippet shows how dependency magic happens. While extending AbstractVerticle we already have an instance of Vertx class. Guice allows injecting dependencies into already constructed instance. And that’s all (almost).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@Log
public class WimbledonVerticle extends AbstractVerticle {

    @Inject
    private TournamentWinnerEndpoint tournamentWinnerEndpoint;

    @Inject
    @Named("port")
    private String port;

    @Override
    public void start() throws Exception {
        //Binds all dependencies to already initialized vertx instance
        Guice.createInjector(new WimbledonModule(vertx)).injectMembers(this);

        Router router = Router.router(vertx);
        router.get("/wimbledon/winner")
          .handler(tournamentWinnerEndpoint::handle);

        vertx.createHttpServer()
          .requestHandler(router::accept)
          .listen(Integer.valueOf(port));

        log.info("WimbledonVerticle starting");
    }
}

Thanks to WimbledonModule we can bind all necessary dependencies. In this example only EventBus instance and properties are binded. Properties comes from config.json file where application port number and Wimbledon players’ names are defined.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class WimbledonModule extends AbstractModule {

    private final Vertx vertx;
    private final Context context;

    public WimbledonModule(Vertx vertx) {
        this.vertx = vertx;
        this.context = vertx.getOrCreateContext();
    }

    @Override
    protected void configure() {
        bind(EventBus.class).toInstance(vertx.eventBus());
        Names.bindProperties(binder(), 
                             extractToProperties(context.config()));
    }

    private Properties extractToProperties(JsonObject config) {
        Properties properties = new Properties();
        config.getMap().keySet().stream().forEach((String key) -> {
            properties.setProperty(key, (String) config.getValue(key));
        });
        return properties;
    }
}

Having it all together we can implement TournamentWinnerEndpoint with injected all needed dependencies.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class TournamentWinnerEndpoint implements Handler<RoutingContext> {

    private final EventBus eventBus;
    private final String player1;
    private final String player2;

    @Inject
    public TournamentWinnerEndpoint(
        EventBus eventBus, 
        @Named("player1") String player1, 
        @Named("player2") String player2) {
        
        this.eventBus = eventBus;
        this.player1 = player1;
        this.player2 = player2;
    }

    @Override
    public void handle(RoutingContext request) {
        Random tournamentKarma = new Random();
        boolean firstPlayerIsAWinner = tournamentKarma.nextBoolean();

        String winner = firstPlayerIsAWinner ? player1 : player2;
        eventBus.send(winner, "Congratulation Wimbledon Winner!");
        request.response().end(winner);
    }
}

And basically this is it. We won twice. Clean, nice looking code and configurable Wimbledon Champion lottery which are ready for all forthcoming Wimbledons.

Final usage:

curl -w " will win Wimbledon in 2015\n" -X GET http://localhost:8080/wimbledon/winner

As a result:

Roger Federer will win Wimbledon in 2015

or

Novak Djokovic will win Wimbledon in 2015

All code is available on Github.

Thanks for reading! BTW: I hope I will manage to write some Tour de France inspired post. Still two weeks until the end.