com.chibchasoft.vertx.verticle.deployment.DependentVerticleDeployer.java Source code

Java tutorial

Introduction

Here is the source code for com.chibchasoft.vertx.verticle.deployment.DependentVerticleDeployer.java

Source

/*
 * Copyright (c) 2017 chibchasoft.com
 * ------------------------------------------------------
 * All rights reserved. This program and the accompanying materials are made
 * available under the terms of the Apache License v2.0 which accompanies
 * this distribution.
 *
 *      The Apache License v2.0 is available at
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Author <a href="mailto:jvelez@chibchasoft.com">Juan Velez</a>
 */
package com.chibchasoft.vertx.verticle.deployment;

import java.util.ArrayList;
import java.util.List;

import io.vertx.core.DeploymentOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.vertx.core.AbstractVerticle;
import io.vertx.core.AsyncResult;
import io.vertx.core.CompositeFuture;
import io.vertx.core.Future;
import io.vertx.core.Handler;

/**
 * <p>Verticle that deploys other verticles which upon successful of themselves may deploy zero or
 * more dependent verticles (and their dependents and so on).</p>
 * <p>If a verticle fails to deploy, none of its dependent verticles are deployed, otherwise all
 * its dependents are deployed at the same time (using either
 * {@link io.vertx.core.Vertx#deployVerticle(String, Handler)} or {@link
 * io.vertx.core.Vertx#deployVerticle(String, DeploymentOptions, Handler)}).</p>
 * <p>The DependentVerticleDeployer completes the future passed to {@link #start(Future)}
 * only and if only ALL deployments (and their dependents and so on) succeed. If any verticle
 * fails to deploy, the future is failed.</p>
 * 
 * @see DependentsDeployment
 * @see DeploymentConfiguration
 * 
 * @author <a href="mailto:jvelez@chibchasoft.com">Juan Velez</a> 
 */
public class DependentVerticleDeployer extends AbstractVerticle {
    private static final Logger LOGGER = LoggerFactory.getLogger(DependentVerticleDeployer.class);
    private DependentsDeployment dependentsDeployment = null;

    public DependentVerticleDeployer() {
    }

    /**
     * Get the {@link DependentsDeployment} to be deployed
     * @return The {@link DependentsDeployment}
     */
    public DependentsDeployment getDependentsDeployment() {
        return dependentsDeployment;
    }

    /**
     * Sets the {@link DependentsDeployment} to be deployed
     * @param dependentsDeployment The {@link DependentsDeployment}
     */
    public void setDependentsDeployment(DependentsDeployment dependentsDeployment) {
        this.dependentsDeployment = dependentsDeployment;
    }

    @Override
    public void start(Future<Void> startFuture) {
        if (dependentsDeployment == null || dependentsDeployment.getConfigurations().isEmpty()) {
            startFuture.complete();
        } else {
            deployDependentsDeployment(startFuture);
        }
    }

    /**
     * Deploys all the verticles configured to be deployed
     * @param startFuture The future for this verticle that needs to be completed once all
     * verticles (and their dependents) are deployed. The future is failed if any verticle fails
     * to be deployed.
     */
    private void deployDependentsDeployment(Future<Void> startFuture) {
        getCompositeFuture().setHandler(ar -> {
            if (ar.failed()) {
                LOGGER.warn("One or more verticles failed to deploy", ar.cause());
                startFuture.fail(ar.cause());
            } else {
                startFuture.complete();
            }
        });

        deployVerticles(dependentsDeployment);
    }

    /**
     * Gets a composite future using a future for each verticle to be deployed. This composite
     * future is successful if all verticles deployed and fails if any verticle fails to deploy.
     * @return The composite future
     */
    private CompositeFuture getCompositeFuture() {
        List<Future<String>> futures = new ArrayList<>();
        dependentsDeployment.getConfigurations().forEach(cfg -> futures.addAll(getFutures(cfg)));

        return CompositeFuture.all(new ArrayList<>(futures));
    }

    /**
     * Adds all futures from {@link DeploymentConfiguration} and its dependents (if any).
     * @param cfg The {@link DeploymentConfiguration}
     */
    private List<Future<String>> getFutures(DeploymentConfiguration cfg) {
        List<Future<String>> futures = new ArrayList<>();
        futures.add(cfg.future);
        for (DependentsDeployment dep : cfg.getDependents()) {
            dep.getConfigurations().forEach(config -> futures.addAll(getFutures(config)));
        }
        return futures;
    }

    /**
     * Deploys each of the verticles found in the DependentsDeployment object
     * @param depDeployment The DependentsDeployment object
     */
    private void deployVerticles(DependentsDeployment depDeployment) {
        if (depDeployment != null && !depDeployment.getConfigurations().isEmpty()) {
            depDeployment.getConfigurations().forEach(this::deployConfiguration);
        }
    }

    /**
     * Using this verticle's vertx, deploy a verticle using the
     * {@link DeploymentConfiguration}. If the verticle to deploy has dependents, those
     * dependents will be deployed when the verticle's deployment succeeds (recursively)
     * @param config The {@link DeploymentConfiguration}
     */
    private void deployConfiguration(DeploymentConfiguration config) {
        String verticleName = config.getName();
        if (LOGGER.isDebugEnabled())
            LOGGER.debug("deploying " + verticleName);
        Handler<AsyncResult<String>> deploymentHandler = res -> {
            if (res.succeeded()) {
                config.future.complete(res.result());
                for (DependentsDeployment dep : config.getDependents()) {
                    deployVerticles(dep);
                }
            } else {
                config.future.fail(res.cause());
                LOGGER.warn("deploying verticle " + verticleName + " failed", res.cause());
            }
        };

        if (config.getDeploymentOptions() != null)
            vertx.deployVerticle(verticleName, config.getDeploymentOptions(), deploymentHandler);
        else
            vertx.deployVerticle(verticleName, deploymentHandler);
    }
}