11package io .neonbee ;
22
3+ import static io .neonbee .config .NeonBeeConfig .BootDeploymentHandling .FAIL_ON_ERROR ;
4+ import static io .neonbee .config .NeonBeeConfig .BootDeploymentHandling .KEEP_PARTIAL ;
35import static io .neonbee .internal .deploy .DeployableModule .fromJar ;
46import static io .neonbee .internal .deploy .DeployableVerticle .fromClass ;
57import static io .neonbee .internal .deploy .DeployableVerticle .fromVerticle ;
4446import io .neonbee .cluster .ClusterManagerFactory ;
4547import io .neonbee .config .HealthConfig ;
4648import io .neonbee .config .NeonBeeConfig ;
49+ import io .neonbee .config .NeonBeeConfig .BootDeploymentHandling ;
4750import io .neonbee .config .ServerConfig ;
4851import io .neonbee .data .DataException ;
4952import io .neonbee .data .DataQuery ;
@@ -566,21 +569,25 @@ private Future<Void> deploySystemVerticles() {
566569 List <Future <? extends Deployable >> requiredVerticles = new ArrayList <>();
567570 requiredVerticles .add (fromClass (vertx , ConsolidationVerticle .class , new JsonObject ().put ("instances" , 1 )));
568571 requiredVerticles .add (fromClass (vertx , LoggerManagerVerticle .class ));
569-
570- List <Future <Optional <? extends Deployable >>> optionalVerticles = new ArrayList <>();
571572 if (Optional .ofNullable (config .getHealthConfig ()).map (HealthConfig ::isEnabled ).orElse (true )) {
572573 requiredVerticles .add (fromClass (vertx , HealthCheckVerticle .class ));
573574 }
575+
576+ List <Future <Optional <? extends Deployable >>> optionalVerticles = new ArrayList <>();
574577 optionalVerticles .add (deployableWatchVerticle (options .getModelsDirectory (), ModelRefreshVerticle ::new ));
575578 optionalVerticles .add (deployableWatchVerticle (options .getModulesDirectory (), DeployerVerticle ::new ));
576579 optionalVerticles .add (deployableRedeployEntitiesJobVerticle (options ));
577580
578581 LOGGER .info ("Deploying system verticles ..." );
579- return all (List .of (fromDeployables (requiredVerticles ).compose (allTo (this )),
580- all (optionalVerticles ).map (CompositeFuture ::list ).map (optionals -> {
581- return optionals .stream ().map (Optional .class ::cast ).filter (Optional ::isPresent ).map (Optional ::get )
582- .map (Deployable .class ::cast ).toList ();
583- }).map (Deployables ::new ).compose (anyTo (this )))).mapEmpty ();
582+ return all (fromDeployables (requiredVerticles ).compose (allTo (this )).onFailure (throwable -> {
583+ LOGGER .error ("Failed to deploy (some / all) required system verticle(s)" , throwable );
584+ }), all (optionalVerticles ).map (CompositeFuture ::list ).map (optionals -> {
585+ return optionals .stream ().map (Optional .class ::cast ).filter (Optional ::isPresent ).map (Optional ::get )
586+ .map (Deployable .class ::cast ).toList ();
587+ }).map (Deployables ::new ).compose (anyTo (this )).onFailure (throwable -> {
588+ LOGGER .error ("Failed to deploy (some / all) optional system verticle(s), bootstrap will continue" ,
589+ throwable );
590+ }).otherwiseEmpty ()).mapEmpty ();
584591 }
585592
586593 private Future <Optional <? extends Deployable >> deployableWatchVerticle (
@@ -621,7 +628,9 @@ private Future<Optional<? extends Deployable>> deployableRedeployEntitiesJobVert
621628 private Future <Void > deployServerVerticle () {
622629 LOGGER .info ("Deploying server verticle ..." );
623630 return fromClass (vertx , ServerVerticle .class , new JsonObject ().put ("instances" , NUMBER_DEFAULT_INSTANCES ))
624- .compose (deployable -> deployable .deploy (this )).mapEmpty ();
631+ .compose (deployable -> deployable .deploy (this )).onFailure (throwable -> {
632+ LOGGER .error ("Failed to deploy server verticle" , throwable );
633+ }).mapEmpty ();
625634 }
626635
627636 /**
@@ -638,11 +647,7 @@ private Future<Void> deployClassPathVerticles() {
638647 return scanForDeployableClasses (vertx ).compose (deployableClasses -> fromDeployables (deployableClasses .stream ()
639648 .filter (verticleClass -> filterByAutoDeployAndProfiles (verticleClass , options .getActiveProfiles ()))
640649 .map (verticleClass -> fromClass (vertx , verticleClass )).collect (Collectors .toList ())))
641- .onSuccess (deployables -> {
642- if (LOGGER .isInfoEnabled ()) {
643- LOGGER .info ("Deploy class path verticle(s) {}." , deployables .getIdentifier ());
644- }
645- }).compose (allTo (this )).mapEmpty ();
650+ .compose (handleBootDeployment ("class path verticle(s)" ));
646651 }
647652
648653 @ VisibleForTesting
@@ -665,7 +670,39 @@ private Future<Void> deployModules() {
665670
666671 LOGGER .info ("Deploying module(s) ..." );
667672 return fromDeployables (moduleJarPaths .stream ().map (moduleJarPath -> fromJar (vertx , moduleJarPath ))
668- .collect (Collectors .toList ())).compose (allTo (this )).mapEmpty ();
673+ .collect (Collectors .toList ())).compose (handleBootDeployment ("module(s)" ));
674+ }
675+
676+ private Function <Deployables , Future <Void >> handleBootDeployment (String deploymentType ) {
677+ BootDeploymentHandling handling = config .getBootDeploymentHandling ();
678+ return deployables -> {
679+ // in case we should keep partial deployments, for every deployable that we are about to deploy
680+ // set the keep partial deployment flag, so that in case there is an error we don't undeploy
681+ if (handling == KEEP_PARTIAL ) {
682+ for (Deployable deployable : deployables .getDeployables ()) {
683+ if (deployable instanceof Deployables ) {
684+ ((Deployables ) deployable ).keepPartialDeployment ();
685+ }
686+ }
687+ }
688+
689+ return (handling == FAIL_ON_ERROR ? allTo (this ) : anyTo (this )).apply (deployables )
690+ .onSuccess (deployments -> {
691+ if (LOGGER .isInfoEnabled ()) {
692+ LOGGER .info ("Successfully deployed all {} {}" ,
693+ deploymentType , deployments .getDeploymentId ());
694+ }
695+ }).recover (throwable -> {
696+ if (LOGGER .isErrorEnabled ()) {
697+ LOGGER .error ("Failed to deploy (some / all) {}{}" ,
698+ deploymentType , handling == FAIL_ON_ERROR ? "" : ", bootstrap will continue" ,
699+ throwable );
700+ }
701+
702+ // abort the boot process if any class path verticle failed to deploy
703+ return handling == FAIL_ON_ERROR ? failedFuture (throwable ) : succeededFuture ();
704+ }).mapEmpty ();
705+ };
669706 }
670707
671708 @ VisibleForTesting
0 commit comments