4
4
import static io .neonbee .internal .deploy .DeployableVerticle .fromClass ;
5
5
import static io .neonbee .internal .deploy .DeployableVerticle .fromVerticle ;
6
6
import static io .neonbee .internal .deploy .Deployables .allTo ;
7
+ import static io .neonbee .config .NeonBeeConfig .BootDeploymentHandling .*;
7
8
import static io .neonbee .internal .deploy .Deployables .anyTo ;
8
9
import static io .neonbee .internal .deploy .Deployables .fromDeployables ;
9
10
import static io .neonbee .internal .helper .ConfigHelper .notFound ;
45
46
import io .neonbee .config .HealthConfig ;
46
47
import io .neonbee .config .NeonBeeConfig ;
47
48
import io .neonbee .config .ServerConfig ;
49
+ import io .neonbee .config .NeonBeeConfig .BootDeploymentHandling ;
48
50
import io .neonbee .data .DataException ;
49
51
import io .neonbee .data .DataQuery ;
50
52
import io .neonbee .entity .EntityModelManager ;
@@ -566,21 +568,25 @@ private Future<Void> deploySystemVerticles() {
566
568
List <Future <? extends Deployable >> requiredVerticles = new ArrayList <>();
567
569
requiredVerticles .add (fromClass (vertx , ConsolidationVerticle .class , new JsonObject ().put ("instances" , 1 )));
568
570
requiredVerticles .add (fromClass (vertx , LoggerManagerVerticle .class ));
569
-
570
- List <Future <Optional <? extends Deployable >>> optionalVerticles = new ArrayList <>();
571
571
if (Optional .ofNullable (config .getHealthConfig ()).map (HealthConfig ::isEnabled ).orElse (true )) {
572
572
requiredVerticles .add (fromClass (vertx , HealthCheckVerticle .class ));
573
573
}
574
+
575
+ List <Future <Optional <? extends Deployable >>> optionalVerticles = new ArrayList <>();
574
576
optionalVerticles .add (deployableWatchVerticle (options .getModelsDirectory (), ModelRefreshVerticle ::new ));
575
577
optionalVerticles .add (deployableWatchVerticle (options .getModulesDirectory (), DeployerVerticle ::new ));
576
578
optionalVerticles .add (deployableRedeployEntitiesJobVerticle (options ));
577
579
578
580
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 ();
581
+ return all (fromDeployables (requiredVerticles ).compose (allTo (this )).onFailure (throwable -> {
582
+ LOGGER .error ("Failed to deploy (some / all) required system verticle(s)" , throwable );
583
+ }), all (optionalVerticles ).map (CompositeFuture ::list ).map (optionals -> {
584
+ return optionals .stream ().map (Optional .class ::cast ).filter (Optional ::isPresent ).map (Optional ::get )
585
+ .map (Deployable .class ::cast ).toList ();
586
+ }).map (Deployables ::new ).compose (anyTo (this )).onFailure (throwable -> {
587
+ LOGGER .error ("Failed to deploy (some / all) optional system verticle(s), bootstrap will continue" ,
588
+ throwable );
589
+ }).otherwiseEmpty ()).mapEmpty ();
584
590
}
585
591
586
592
private Future <Optional <? extends Deployable >> deployableWatchVerticle (
@@ -621,7 +627,9 @@ private Future<Optional<? extends Deployable>> deployableRedeployEntitiesJobVert
621
627
private Future <Void > deployServerVerticle () {
622
628
LOGGER .info ("Deploying server verticle ..." );
623
629
return fromClass (vertx , ServerVerticle .class , new JsonObject ().put ("instances" , NUMBER_DEFAULT_INSTANCES ))
624
- .compose (deployable -> deployable .deploy (this )).mapEmpty ();
630
+ .compose (deployable -> deployable .deploy (this )).onFailure (throwable -> {
631
+ LOGGER .error ("Failed to deploy server verticle" , throwable );
632
+ }).mapEmpty ();
625
633
}
626
634
627
635
/**
@@ -638,11 +646,7 @@ private Future<Void> deployClassPathVerticles() {
638
646
return scanForDeployableClasses (vertx ).compose (deployableClasses -> fromDeployables (deployableClasses .stream ()
639
647
.filter (verticleClass -> filterByAutoDeployAndProfiles (verticleClass , options .getActiveProfiles ()))
640
648
.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 ();
649
+ .compose (handleBootDeployment ("class path verticle(s)" ));
646
650
}
647
651
648
652
@ VisibleForTesting
@@ -665,7 +669,39 @@ private Future<Void> deployModules() {
665
669
666
670
LOGGER .info ("Deploying module(s) ..." );
667
671
return fromDeployables (moduleJarPaths .stream ().map (moduleJarPath -> fromJar (vertx , moduleJarPath ))
668
- .collect (Collectors .toList ())).compose (allTo (this )).mapEmpty ();
672
+ .collect (Collectors .toList ())).compose (handleBootDeployment ("module(s)" ));
673
+ }
674
+
675
+ private Function <Deployables , Future <Void >> handleBootDeployment (String deploymentType ) {
676
+ BootDeploymentHandling handling = config .getBootDeploymentHandling ();
677
+ return deployables -> {
678
+ // in case we should keep partial deployments, for every deployable that we are about to deploy
679
+ // set the keep partial deployment flag, so that in case there is an error we don't undeploy
680
+ if (handling == KEEP_PARTIAL ) {
681
+ for (Deployable deployable : deployables .getDeployables ()) {
682
+ if (deployable instanceof Deployables ) {
683
+ ((Deployables ) deployable ).keepPartialDeployment ();
684
+ }
685
+ }
686
+ }
687
+
688
+ return (handling == FAIL_ON_ERROR ? allTo (this ) : anyTo (this )).apply (deployables )
689
+ .onSuccess (deployments -> {
690
+ if (LOGGER .isInfoEnabled ()) {
691
+ LOGGER .info ("Successfully deployed all {} {}" ,
692
+ deploymentType , deployments .getDeploymentId ());
693
+ }
694
+ }).recover (throwable -> {
695
+ if (LOGGER .isErrorEnabled ()) {
696
+ LOGGER .error ("Failed to deploy (some / all) {}{}" ,
697
+ deploymentType , handling == FAIL_ON_ERROR ? "" : ", bootstrap will continue" ,
698
+ throwable );
699
+ }
700
+
701
+ // abort the boot process if any class path verticle failed to deploy
702
+ return handling == FAIL_ON_ERROR ? failedFuture (throwable ) : succeededFuture ();
703
+ }).mapEmpty ();
704
+ };
669
705
}
670
706
671
707
@ VisibleForTesting
0 commit comments