javavert.xvertx4java-vertx-web

Vertx Web Resource Not Found


In one of the projects that I'm working on I register routes onto the Router dynamically like below.

vertx.eventBus().consumer("REGISTER_ROUTE", handler -> {
      JsonObject message = (JsonObject) handler.body();
      HttpMethod method = HttpMethod.valueOf(message.getString("method"));
      router.route(method, message.getString("url"))
        .order(1)
        .handler(cxt -> cxt.json(new JsonObject().put("message", "This works..!!")));
    });

And this event is triggered from another verticle like this

vertx.eventBus().send("REGISTER_ROUTE",
        new JsonObject()
          .put("url", "/test-route")
          .put("method", "GET")
      );

Issue is that on windows machine this almost always works. But on a testing linux instance on AWS

Last two of the scenarios not very sure what's the correlation to number 3(since this success/error response seems to refresh on a cycle of 3 subsequent requests). Thought it could be to number of instances of the server verticle. But modifying the instance count doesn't change this behavior either.

I have a custom error handler for 404 registered like below

router.errorHandler(404, routingContext -> {
      LOGGER.info("HTTP-404 Error Handler invoked");
      LOGGER.info("Router :" + router.toString() + " Routes Size: " + router.getRoutes().size());
      JsonObject error = new JsonObject()
        .put("error", "Resource not found");
      routingContext.response()
        .setStatusCode(404)
        .putHeader(HttpHeaders.CONTENT_TYPE, "application/json")
        .end(error.toBuffer());
    });

Whenever a 404 response is received I could see from the logs that router states does show there is a route declared with the given PATH and HTTP method combination.

I have tried registering route using the HTTP method specific syntax like router.get(url), that didn't seem to make any difference either.

Vert.x Version: 4.2.7

JDK: Eclipse Temurin 11.0.14.1+1

OS: Centos 7 on EC2

Problem is that issue doesn't occur always so it's becoming more and more difficult to identify the root cause and fix it.

Please let me know if there is anything that is wrong/missing in this. Also I have created a sample project here. This is a close replica of what I have on my actual project. Note: The issue didn't generally occur to me on Windows (for whatever reasons).


Solution

  • In App class, 4 instances of each verticle are deployed.

    vertx.deployVerticle(Server.class.getName(), new DeploymentOptions().setInstances(4))
          .compose(server -> {
            return vertx.deployVerticle(RouteRegistration.class.getName(), new DeploymentOptions().setInstances(4))
              .onSuccess(id -> LOGGER.info("Application started Successfully"))
              .onFailure(LOGGER::catching);
          });vertx.deployVerticle(Server.class.getName(), new DeploymentOptions().setInstances(4))
          .compose(server -> {
            return vertx.deployVerticle(RouteRegistration.class.getName(), new DeploymentOptions().setInstances(4))
              .onSuccess(id -> LOGGER.info("Application started Successfully"))
              .onFailure(LOGGER::catching);
          });
    

    This means that:

    Consequently, connections will be handled by different routers with different setups.

    On your local machine, I don't know why it works, perhaps you deploy a single instance?

    Anyway, to fix the issue, you must have the same router configuration in every router instance, so the RouteRegistration must publish the message so that every consumer instance gets it:

    vertx.eventBus().publish("REGISTER_ROUTE",
          new JsonObject()
            .put("url", "/test-route")
            .put("method", "GET")
        );