All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ph.com.nightowlstudios.core.ApplicationVerticle Maven / Gradle / Ivy

There is a newer version: 6.21.1
Show newest version
package ph.com.nightowlstudios.core;

import io.vertx.core.*;
import io.vertx.core.http.HttpHeaders;
import io.vertx.core.http.HttpMethod;
import io.vertx.core.http.HttpServer;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.bridge.PermittedOptions;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.handler.ErrorHandler;
import io.vertx.ext.web.handler.LoggerHandler;
import io.vertx.ext.web.handler.sockjs.SockJSBridgeOptions;
import io.vertx.ext.web.handler.sockjs.SockJSHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ph.com.nightowlstudios.resource.Resource;
import ph.com.nightowlstudios.service.Service;

import java.util.*;

/**
 * @author Joseph Harvey Angeles - @yev
 * @since 7/14/20
 */
public abstract class ApplicationVerticle extends AbstractVerticle {

  private final HttpServerVerticle serverVerticle;
  private final Map, DeploymentOptions> serviceVerticles;

  public ApplicationVerticle() {
    this.serviceVerticles = new HashMap<>();
    this.serverVerticle = new HttpServerVerticle(
      this::allowCORSCredentials,
      this::allowedMethods,
      this::allowedHeaders,
      this::exposedHeaders,
      this::apiPrefix,
      this::beforeRouterCreate,
      this::createRouteLogHandler,
      this::createRouteFailureHandler,
      this::getResourceClasses,
      this::setupRoutes,
      this::webSocketPrefix,
      this::createWebSocketRouter,
      this::bannerText,
      this::onStart,
      this::onStartFail
    );
  }

  @Override
  public void start(Promise startPromise) {
    setup();
    CompositeFuture.all(buildDeployList())
      .onSuccess(none -> startPromise.complete())
      .onFailure(failure -> {
        log.error("Unable to deploy Edge Application", failure.getCause());
        startPromise.fail(failure.getMessage());
      });
  }

  /**
   * This is the very first method to be called when launching the main verticle.
   * This is where {@link ph.com.nightowlstudios.service.Service} verticles should be registered using any of the {@link #registerService(Class[])}
   * 

* An Http server verticle is also automatically internally registered to Http requests. * * @see ph.com.nightowlstudios.service.Service */ public abstract void setup(); private List buildDeployList() { List list = new ArrayList<>(); this.serviceVerticles.forEach((service, options) -> list.add(createLauncher(service, options))); list.add(createLauncher(this.serverVerticle)); return list; } @SuppressWarnings("unchecked") private Future createLauncher(Class service, DeploymentOptions options) { // Merge the global `application.yml` config the `DeploymentOptions` options.setConfig(Optional .ofNullable(options.getConfig()) .orElse(new JsonObject()) .mergeIn(config()) ); return vertx.deployVerticle((Class) service, options) .onSuccess(none -> log.info("Deployed {} verticle successfully.", service.getName())) .onFailure(failure -> log.error("Error deploying {}.", service.getName())); } private Future createLauncher(Verticle verticle) { return vertx.deployVerticle(verticle, new DeploymentOptions().setConfig(config())); } @SafeVarargs protected final void registerService(Class... services) { for (Class service : services) { this.registerService(service, new DeploymentOptions()); } } protected void registerService(Class service, DeploymentOptions options) { this.serviceVerticles.put(service, options); Edge.registerService(service); } /** * Called immediately after Router creation. * * @param router the root router */ protected void beforeRouterCreate(Router router) { } /** * Called before mounting API subrouter. * * @param apiRouter api subrouter */ protected void setupRoutes(Router apiRouter) { } /** * Called when the HttpServer has been started. * * @param httpServer the started server */ protected void onStart(HttpServer httpServer) { } /** * Called when the HttpServer failed to start * * @param error cause of the failure */ protected void onStartFail(Throwable error) { } protected final String appName() { return config().getString("name", "edge.api"); } protected final String version() { return config().getString("version", "1.0"); } protected boolean allowCORSCredentials() { return true; } protected Set allowedMethods() { return ALLOWED_METHODS; } protected Set allowedHeaders() { return ALLOWED_HEADERS; } protected Set exposedHeaders() { return EXPOSED_HEADERS; } protected String apiPrefix() { String prefix = config().getString("prefix", "api"); return String.format("/%s/%s", prefix.trim(), version().trim()); } protected String webSocketPrefix() { return config().getString("wsPrefix", "/ws"); } protected String bannerText() { return BANNER_TXT; } protected Handler createRouteLogHandler() { return LoggerHandler.create(); } protected Handler createRouteFailureHandler() { return ErrorHandler.create(getVertx()); } @SuppressWarnings("unchecked") protected abstract Class[] getResourceClasses(); private Router createWebSocketRouter(Vertx vertx) throws RuntimeException { SockJSHandler handler = SockJSHandler.create(vertx); SockJSBridgeOptions options = new SockJSBridgeOptions(); List inbound = new ArrayList<>(addInboundSocketRules()); options.setInboundPermitteds(inbound); List outbound = new ArrayList<>(addOutboundSocketRules()); options.setOutboundPermitteds(outbound); return handler.bridge(options); } protected List addInboundSocketRules() { return new ArrayList<>(); } protected List addOutboundSocketRules() { return new ArrayList<>(); } private static final Logger log = LoggerFactory.getLogger(ApplicationVerticle.class); private static final Set ALLOWED_METHODS = new HashSet<>( Arrays.asList( HttpMethod.GET, HttpMethod.PUT, HttpMethod.POST, HttpMethod.PATCH, HttpMethod.DELETE, HttpMethod.OPTIONS ) ); private static final Set ALLOWED_HEADERS = new HashSet<>( Arrays.asList( HttpHeaders.CONTENT_TYPE.toString(), HttpHeaders.AUTHORIZATION.toString(), HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN.toString(), HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS.toString(), HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD.toString(), HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS.toString() ) ); private static final Set EXPOSED_HEADERS = new HashSet<>(Collections.singletonList(HttpHeaders.AUTHORIZATION.toString())); static final String BANNER_TXT = "\n" + "▓█████ ▓█████▄ ▄████ ▓█████ \n" + "▓█ ▀ ▒██▀ ██▌ ██▒ ▀█▒▓█ ▀ \n" + "▒███ ░██ █▌▒██░▄▄▄░▒███ \n" + "▒▓█ ▄ ░▓█▄ ▌░▓█ ██▓▒▓█ ▄ \n" + "░▒████▒░▒████▓ ░▒▓███▀▒░▒████▒ \n" + "░░ ▒░ ░ ▒▒▓ ▒ ░▒ ▒ ░░ ▒░ ░ \n" + " ░ ░ ░ ░ ▒ ▒ ░ ░ ░ ░ ░ \n" + " ░ ░ ░ ░ ░ ░ ░ ░ \n" + " ░ ░ ░ ░ ░ ░ \n" + " ░ \n"; }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy