如何在Quarkus中管理CompletableFuture.completeExceptionally()

时间:2019-06-07 13:27:34

标签: vert.x quarkus

我正在将Quarkus与Vertx异步消息传递一起使用。一切正常,但是使用CompletableFuture.completeExceptionally()时我无法使EventBus工作。这意味着在Service.shareTicket()方法中,我可以在whenComplete块中捕获异常,但在TicketResource.shareTicket()方法中,不能捕获异常。

我收到此错误:

  

执行POST / tickets / DF123456789123456789时发生未知异常:   (TIMEOUT,-1)等待30000(ms)答复后超时。地址:   __vertx.reply.9,已回复地址:Service.shareTicket           在io.vertx.core.eventbus.impl.HandlerRegistration.sendAsyncResultFailure(HandlerRegistration.java:146)           在io.vertx.core.eventbus.impl.HandlerRegistration.lambda $ new $ 0(HandlerRegistration.java:78)           在io.vertx.core.impl.VertxImpl $ InternalTimerHandler.handle(VertxImpl.java:907)           在io.vertx.core.impl.VertxImpl $ InternalTimerHandler.handle(VertxImpl.java:866)           在io.vertx.core.impl.ContextImpl.executeTask(ContextImpl.java:320)           在io.vertx.core.impl.EventLoopContext.lambda $ executeAsync $ 0(EventLoopContext.java:38)           在io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)           在io.netty.util.concurrent.SingleThreadEventExecutor.runAllTask​​s(SingleThreadEventExecutor.java:404)           在io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:495)           在io.netty.util.concurrent.SingleThreadEventExecutor $ 5.run(SingleThreadEventExecutor.java:905)           在io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)           在java.base / java.lang.Thread.run(Thread.java:834)

任何帮助将不胜感激

RestResource

import io.vertx.axle.core.eventbus.EventBus;
import io.vertx.core.json.JsonObject;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;

@ApplicationScoped
@Path("/tickets")
public class TicketResource {

    @Inject
    EventBus bus;

    @POST
    @Produces(MediaType.APPLICATION_JSON)
    @Path("{ticket_id}")
    public CompletionStage<JsonObject> shareTiket(@PathParam("ticket_id") @Valid @NotEmpty String id) {

        CompletableFuture<JsonObject> future = new CompletableFuture<>();

        this.bus.<JsonObject>send(Service.SHARE_TICKET, id).whenComplete((jsonObjectMessage, throwable) -> {

            if (null != throwable) {
                future.completeExceptionally(throwable);
            } else {
                future.complete(jsonObjectMessage.body());
            }

            System.out.println("EXITED");
        }).thenApply(jsonObject -> {

            System.out.println("RECEIVED " + jsonObject.body());
            return jsonObject.body();
        });

        return future;
    }
}

服务

import io.quarkus.vertx.ConsumeEvent;
import io.vertx.core.eventbus.EventBus;
import io.vertx.core.json.JsonObject;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;

@ApplicationScoped
public class ServiceImpl implements Service {

    @Inject
    EventBus bus;
    @Inject
    io.vertx.axle.core.eventbus.EventBus axleBus;

    @Override
    @ConsumeEvent(SHARE_TICKET)
    public CompletionStage<JsonObject> shareTicket(String id) {

        CompletableFuture<JsonObject> future = new CompletableFuture<>();

        this.getFromRestService(id)
                .thenComposeAsync(this::insertIntoMongo)
                .whenComplete((result, ex) -> {
                    if (null != ex) {
                        future.completeExceptionally(ex);
                    } else {
                        future.complete(result);
                    }
                });

        return future;
    }

    /**
     * send a message to RestClient asking to retrieve received id's Ticket data
     *
     * @param id the id of the Ticket to select data
     * @return a Ticket
     */
    private CompletionStage<Ticket> getFromRestService(String tsn) {

        CompletableFuture<Ticket> future = new CompletableFuture<>();

        // create request
        TicketRequest getTicketReq = new TicketRequest(tsn);

        // send message to RestClient
        this.axleBus.<JsonObject>send(
                RestClient.TICKET_MESSAGES_ADDRESS,
                getTicketReq.toJsonObject()).thenApply(jsonObjMex -> {

            TicketResponse ticketResponse = jsonObjMex.body().mapTo(TicketResponse.class);

            try {
                // check response integrity
                ResponseHelper.checkGetTicketResponse(ticketResponse);

                throw new MyRestClientException("test");

//                future.complete(ticket);

            } catch (MyRestClientException e) {
                future.completeExceptionally(e);
            }

            return jsonObjMex;
        });

        return future;
    }


    /**
     * save the received Ticket into mongodb
     *
     * @param ticket the Ticket to save into mongo
     */
    private CompletionStage<JsonObject> insertIntoMongo(Ticket ticket) {

        CompletableFuture<JsonObject> future = new CompletableFuture<>();

        this.bus.<JsonObject>send(
                MongoDbClient.SAVE_TICKET,
                ticket.toJsonObject(),
                ar -> {
                    if (ar.succeeded()) {

                        System.out.println("TICKET SAVED (SERVICE): " + ar.result().body());
                        future.complete(ar.result().body());
                    } else {
                        future.completeExceptionally(ar.cause());
                    }
                });

        return future;
    }
}

0 个答案:

没有答案