0
votes

I'm quite new to the Microservice world and particularly vertX. I want my verticle to start anyway even there is no database connection available (e.g. database URL missing in configuration). I already managed to do this and my verticle is starting.

The issue now is that I want my verticle to notice when the database connection is available again and connect to it. How can I do this ? I thought about creating another Verticle "DatabaseVerticle.java" which would send the current DB config on the event bus and my initial verticle would consume this message and check whether the config info is consistent (reply with success) or still missing some data (reply with fail and make the DatabaseVerticle check again).

This might work (and might not) but does not seem to be the optimal solution for me.

I'd be very glad if someone could suggest a better solution. Thank you !

3

3 Answers

1
votes

For your use case, I'd recommend to use the vertx-config. In particular, have a look at the Listening to configuration changes section of the Vert.x Config documentation.

You could create a config retriever and set a handler for changes:

ConfigRetrieverOptions options = new ConfigRetrieverOptions()
  .setScanPeriod(2000)
  .addStore(myConfigStore);

ConfigRetriever retriever = ConfigRetriever.create(vertx, options);
retriever.getConfig(json -> {
  // If DB config available, start the DB client
  // Otherwise set a "dbStarted" variable to false
});

retriever.listen(change -> {
  // If "dbStarted" is still set to false
  // Check the config and start the DB client if possible
  // Set "dbStarted" to true when done
});
0
votes

The ideal way would be some other service telling your service about database connection. Either through event bus or HTTP, what you can do is when someone tries to access your database when connection is not made just try to make some DB call and handle the exception, return a boolean as false. Now when you get a message on event bus, consume it and save it in some config pojo. Now when someone tries to access your database, look for config and if available make a connection.

Your consumer:

public void start(){
    EventBus eb = vertx.eventBus();
    eb.consumer("database", message -> {
        config.setConfig(message.body());
    });
}

Your db client(Mongo for this eg):

public class MongoService{

    private MongoClient client;
    public boolean isAvailable = false;

    MongoService(Vertx vertx){
        if(config().getString("connection")){
            client = MongoClient.createShared(vertx, config().getString("connection"));
            isAvailable = true;
        }
    }
}
0
votes

Not everything in Vertx should be solved by another verticle.
In this case, you can use .periodic()
http://vertx.io/docs/vertx-core/java/#_don_t_call_us_we_ll_call_you

I assume you have some function that checks the DB for the first time.
Let's call it checkDB()

class PeriodicVerticle extends AbstractVerticle {

    private Long timerId;

    @Override
    public void start() {
        System.out.println("Started");
        // Should be called each time DB goes offline
        final Long timerId = this.vertx.setPeriodic(1000, (l) -> {

            final boolean result = checkDB();
            // Set some variable telling verticle that DB is back online
            if (result) {
                cancelTimer();
            }
        });

        setTimerId(timerId);

    }

    private void cancelTimer() {
        System.out.println("Cancelling");
        getVertx().cancelTimer(this.timerId);
    }

    private void setTimerId(final Long timerId) {
        this.timerId = timerId;
    }
}

Here I play a bit with timerId, since we cannot pass it to cancelTimer() right away. But otherwise, it's quite simple.