package de.pzzz.vertx; import java.util.logging.Logger; import io.vertx.config.ConfigRetriever; import io.vertx.core.AbstractVerticle; import io.vertx.core.Future; import io.vertx.core.Promise; import io.vertx.core.http.HttpMethod; import io.vertx.core.json.JsonObject; import io.vertx.ext.web.Router; import io.vertx.ext.web.handler.BodyHandler; import io.vertx.ext.web.handler.CorsHandler; import io.vertx.ext.web.handler.StaticHandler; public abstract class ServerVerticle extends AbstractVerticle { private static final Logger LOG = Logger.getLogger(ServerVerticle.class.getName()); public static final String API_URL_BASE = "/api/v1"; private Router router; @Override public void start(Promise startPromise) throws Exception { super.start(); long startTime = System.currentTimeMillis(); initConfig().compose(this::setupRouter) .compose(this::initServerLogic) .compose(this::setupStaticRoutes) .compose(this::startServer) .onComplete(result -> LOG.info(() -> "Started in " + (System.currentTimeMillis() - startTime) + "ms")) .onFailure(error -> { error.printStackTrace(); startPromise.fail(error.getMessage()); }) .onComplete(startPromise); } protected abstract Future setupServerLogic(final Startup startup, final Router router); private Future initConfig() { ConfigRetriever configRetriever = ConfigRetriever.create(vertx); configRetriever.getConfig(); return configRetriever.getConfig().map(Startup::new); } private Future setupRouter(final Startup startup) { router = Router.router(vertx); router.route(API_URL_BASE + "/*") .handler(CorsHandler.create() .addOrigin("*") .allowedMethod(HttpMethod.GET) .allowedMethod(HttpMethod.POST) .allowedMethod(HttpMethod.PUT) .allowedMethod(HttpMethod.DELETE) .allowedMethod(HttpMethod.OPTIONS) .allowedHeader("Access-Control-Request-Method") .allowedHeader("Access-Control-Allow-Credentials") .allowedHeader("Access-Control-Allow-Origin") .allowedHeader("Access-Control-Allow-Headers") .allowedHeader("Content-Type") .allowedHeader("Origin") .allowedHeader("Accept") .allowedHeader("Authorization")); router.route(API_URL_BASE + "/*").handler(BodyHandler.create()); return Future.succeededFuture(startup); } private Future initServerLogic(final Startup startup) { return setupServerLogic(startup, router); } private Future setupStaticRoutes(final Startup startup) { router.route("/*").handler(StaticHandler.create()); router.get().handler(context -> context.response().sendFile("webroot/index.html")); return Future.succeededFuture(startup); } private Future startServer(final Startup startup) { JsonObject httpConfig = startup.getConfig().getJsonObject("http", new JsonObject()); int port = httpConfig.getInteger("port", 8080); vertx.createHttpServer().requestHandler(router).listen(port); return Future.succeededFuture(); } }