0

Using vert.x EventBus in a custom AuthProvider does give "Internal Server Error" on future completion.

Built a custom AuthProvider, which gets user data from EventBus. EventBus and user data are returned correctly, but after succeededFuture() the handler I only get "Internal Server Error". Do I mess up the handler and async mode of EventBus.send()?

package tld.domain.auth;

import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.Vertx;
import io.vertx.core.eventbus.EventBus;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.auth.AuthProvider;
import io.vertx.ext.auth.User;

public class MyAuthProvider implements AuthProvider {

    private final EventBus eventBus;

    public MyAuthProvider(Vertx vertx) {
        this.eventBus = vertx.eventBus();
    }

    public static MyAuthProvider create(Vertx vertx) {
        return new MyAuthProvider(vertx);
    }

    @Override
    public void authenticate(JsonObject jsonObject, Handler<AsyncResult<User>> handler) {

        try {
            eventBus.send("hello", null, message -> {
                try {
                    if (true) {
                        handler.handle(Future.succeededFuture(new MyAuthUser()));
                    } else {
                        handler.handle(Future.failedFuture("failed by purpose"));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

package tld.domain.auth;

import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.auth.AbstractUser;
import io.vertx.ext.auth.AuthProvider;

public class MyAuthUser extends AbstractUser {
    @Override
    protected void doIsPermitted(String s, Handler<AsyncResult<Boolean>> handler) {
        handler.handle(Future.succeededFuture(true));
    }

    @Override
    public JsonObject principal() {
        return null;
    }

    @Override
    public void setAuthProvider(AuthProvider authProvider) {

    }
}

And in the verticle

_router = Router.router(vertx);

MyAuthProvider authProvider = MyAuthProvider.create(vertx);

// router auth session storage
_router.route().handler(CookieHandler.create());
_router.route().handler(SessionHandler.create(LocalSessionStore.create(vertx)).setAuthProvider(authProvider));

// router basic auth
AuthHandler basicAuthHandler = BasicAuthHandler.create(authProvider);
_router.route().handler(basicAuthHandler);

_router.route().handler(BodyHandler.create());
_router.get("/hello").handler(this::getHelloHandler);

Removing the eventbus.send() makes the example working (getting the proper response). Adding the eventbus messes the result up only getting "Internal Server Error" instead of a response.

Is there an issue with handler and async eventbus.send(), or do I miss some other important vert.x concept?

J. Hauser
  • 233
  • 1
  • 16
  • try sending some text or JSON instead of `null` – injecteer Jun 05 '19 at 12:57
  • This is just an example, in my real application, i send the the user json, and get back the correct user. Still it hangs, so i simplified down the example. – J. Hauser Jun 05 '19 at 13:03
  • you need to paste your exception trace. "Internal Server Error" tells us nothing – injecteer Jun 05 '19 at 13:05
  • There is no exception trace. Even IntelliJ does not catch any exception! – J. Hauser Jun 05 '19 at 13:07
  • I think the exception is might be eaten by vertx on it's way. You would have to enclose the suspicious block -> `event.send(...)` in a `try-catch` and log the stacktrace from there – injecteer Jun 05 '19 at 13:09
  • ```java _eventBus.send(DB_SELECT_MESSAGE, item, message -> { if (message.succeeded()) { //since username is PK there is no need to check for multiple entries tld.domain.dto.user.User body = (tld.domain.dto.user.User) message.result().body(); ``` – J. Hauser Jun 05 '19 at 13:10
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/194486/discussion-between-injecteer-and-j-hauser). – injecteer Jun 05 '19 at 13:11

1 Answers1

1

I found the solution by swapping the BodyHandler and the AuthHandler registering order.

// BodyHandler FIRST !!!
_router.route().handler(BodyHandler.create());
// AuthHandler SECOND
_router.route().handler(_basicAuthHandler);
// DO NOT CREATE BodyHandler AFTER AuthHandler
//_router.route().handler(BodyHandler.create());
J. Hauser
  • 233
  • 1
  • 16