@Override
    public void start(Future<Void> startFuture) {
        Future<Void> superFuture = Future.future();
        Future<HttpServer> listenFuture = Future.future();
        super.start(superFuture);

        CompositeFuture.all(superFuture, listenFuture)
            .setHandler(compositeResult -> {
                if (compositeResult.succeeded()) {
                    startFuture.complete(null);
                } else {
                    startFuture.fail(compositeResult.cause());
                }
            });

        VertxResteasyDeployment deployment = new VertxResteasyDeployment();
        deployment.start();

        addResources(deployment.getRegistry(),
                new SystemResourceImpl(apimanConfig, engine),
                new ApiResourceImpl(apimanConfig, engine),
                new ClientResourceImpl(apimanConfig, engine),
                new OrgResourceImpl(apimanConfig, engine)
        );

        deployment.getProviderFactory().register(RestExceptionMapper.class);

        VertxRequestHandler resteasyRh = new VertxRequestHandler(vertx, deployment);

        Router router = Router.router(vertx)
                    .exceptionHandler(error -> log.error(error.getMessage(), error));

        // Ensure body handler is attached early so that if AuthHandler takes an external action
        // we don't end up losing the body (e.g OAuth2).
        router.route()
            .handler(BodyHandler.create());

        AuthHandler authHandler = AuthFactory.getAuth(vertx, router, apimanConfig);

        // Everything except system/status requires auth.
        router.routeWithRegex("^((?!/system/status).)*$")
            .handler(authHandler);

        router.route("/*") // We did the previous stuff, now we call into JaxRS.
            .handler(context -> resteasyRh.handle(new Router2ResteasyRequestAdapter(context)));

        HttpServerOptions httpOptions = new HttpServerOptions();

        if (apimanConfig.isSSL()) {
            httpOptions.setSsl(true)
                .setKeyStoreOptions(
                        new JksOptions()
                            .setPath(apimanConfig.getKeyStore())
                            .setPassword(apimanConfig.getKeyStorePassword())
                        )
                .setTrustStoreOptions(
                    new JksOptions()
                        .setPath(apimanConfig.getTrustStore())
                        .setPassword(apimanConfig.getTrustStorePassword())
                );
            addAllowedSslTlsProtocols(httpOptions);
        } else {
            log.warn("API is running in plaintext mode. Enable SSL in config for production deployments.");
        }

        vertx.createHttpServer(httpOptions)
            .requestHandler(router::accept)
            .listen(apimanConfig.getPort(VERTICLE_TYPE),
                    apimanConfig.getHostname(),
                    listenFuture.completer());
    }
API verticle provides the Gateway API RESTful API. Config is validated and pushed into the registry
component; hence, if a distributed component such as ElasticSearch is used, this is shared across all nodes
extending {@link ApimanVerticleWithEngine}.

@author Marc Savy {@literal <msavy@redhat.com>}
gateway/platforms/vertx3/vertx3/src/main/java/io/apiman/gateway/platforms/vertx3/verticles/ApiVerticle.java