3434import com .marklogic .mgmt .mapper .DefaultResourceMapper ;
3535import com .marklogic .mgmt .mapper .ResourceMapper ;
3636import com .marklogic .mgmt .resource .databases .DatabaseManager ;
37+ import com .marklogic .mgmt .resource .forests .ForestManager ;
3738import com .marklogic .mgmt .util .ObjectMapperFactory ;
3839import com .marklogic .rest .util .JsonNodeUtil ;
3940
4041import java .io .File ;
4142import java .io .FilenameFilter ;
4243import java .io .IOException ;
43- import java .util .*;
44+ import java .util .ArrayList ;
45+ import java .util .Collections ;
46+ import java .util .HashMap ;
47+ import java .util .HashSet ;
48+ import java .util .LinkedHashMap ;
49+ import java .util .List ;
50+ import java .util .Map ;
51+ import java .util .Set ;
52+ import java .util .stream .Collectors ;
4453
4554/**
4655 * As of release 3.14.0, this now handles all databases, not just "databases other than the default content database".
@@ -161,7 +170,7 @@ public void undo(CommandContext context) {
161170 /**
162171 * If no database files are found, may still need to delete the content database in case no file exists for it.
163172 * That's because the command for creating a REST API server will not delete the content database by default.
164- *
173+ * <p>
165174 * Per ticket #404, this will now do a check to see if the default content database filename is ignored. If so,
166175 * and there are no database files found, then the content database will not be deleted.
167176 *
@@ -392,6 +401,8 @@ protected void buildDeployDatabaseCommands(CommandContext context, List<Database
392401 * @param databasePlans
393402 */
394403 protected void deployDatabasesAndForestsViaCma (CommandContext context , List <DatabasePlan > databasePlans ) {
404+ addForestMapToCommandContext (context , databasePlans );
405+
395406 Configuration dbConfig = new Configuration ();
396407 // Forests must be included in a separate configuration object
397408 Configuration forestConfig = new Configuration ();
@@ -415,6 +426,28 @@ protected void deployDatabasesAndForestsViaCma(CommandContext context, List<Data
415426 });
416427 }
417428
429+ /**
430+ * Added to greatly speed up performance when getting details about all the existing primary forests for each
431+ * database referenced by a plan. In the event that anything fails, the map won't be added to the command context
432+ * and any code expecting to use the map will just have to fall back to use /manage/v2.
433+ *
434+ * @param context
435+ * @param databasePlans
436+ */
437+ private void addForestMapToCommandContext (CommandContext context , List <DatabasePlan > databasePlans ) {
438+ try {
439+ Set <String > dbNames = databasePlans .stream ().map (plan -> plan .getDatabaseName ()).collect (Collectors .toSet ());
440+ logger .info ("Retrieving all forest details via CMA" );
441+ long start = System .currentTimeMillis ();
442+ Map <String , List <Forest >> forestMap = new ForestManager (context .getManageClient ()).getPrimaryForestsForDatabases (dbNames .toArray (new String []{}));
443+ logger .info ("Finished retrieving all forests details via CMA; duration: " + (System .currentTimeMillis () - start ));
444+ context .getContextMap ().put ("ml-app-deployer-forestMap" , forestMap );
445+ } catch (Exception ex ) {
446+ logger .warn ("Unable to retrieve all forest details, cause: " + ex .getMessage () + "; will fall back to " +
447+ "using /manage/v2 when needed for getting details for a forest." );
448+ }
449+ }
450+
418451 /**
419452 * Each DatabasePlan is expected to have constructed a DeployForestCommand, but not executed it. Each
420453 * DeployForestCommand can then be used to build a list of forests. All of those forests can be combined into a
0 commit comments