Skip to content
This repository was archived by the owner on Sep 16, 2024. It is now read-only.

Commit 8037852

Browse files
committed
#389 Replicas are now spread across hosts correctly
ForestBuilder was correct, but ConfigureForestReplicasCommand was only passing it one forest at a time
1 parent 2b1476d commit 8037852

File tree

3 files changed

+63
-22
lines changed

3 files changed

+63
-22
lines changed

src/main/java/com/marklogic/appdeployer/command/forests/ConfigureForestReplicasCommand.java

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,45 @@ protected void deleteReplicas(String forestName, ForestManager forestMgr) {
108108
* @param context
109109
*/
110110
protected void configureDatabaseReplicaForests(String databaseName, int replicaCount, List<String> hostNames, CommandContext context) {
111+
List<Forest> forestsNeedingReplicas = determineForestsNeedingReplicas(databaseName, context);
112+
113+
ForestBuilder forestBuilder = new ForestBuilder();
114+
List<String> selectedHostNames = getHostNamesForDatabaseForests(databaseName, hostNames, context);
115+
ForestPlan forestPlan = new ForestPlan(databaseName, selectedHostNames).withReplicaCount(replicaCount);
116+
List<String> dataDirectories = forestBuilder.determineDataDirectories(databaseName, context.getAppConfig());
117+
forestBuilder.addReplicasToForests(forestsNeedingReplicas, forestPlan, context.getAppConfig(), dataDirectories);
118+
119+
// TODO Use CMA here in the future? Need to test to see if a forest name + replicas are allowable
120+
ForestManager forestManager = new ForestManager(context.getManageClient());
121+
for (Forest forest : forestsNeedingReplicas) {
122+
final String forestName = forest.getForestName();
123+
124+
Forest forestWithOnlyReplicas = new Forest();
125+
forestWithOnlyReplicas.setForestReplica(forest.getForestReplica());
126+
String json = forestWithOnlyReplicas.getJson();
127+
128+
logger.info(format("Creating forest replicas for primary forest %s", forestName));
129+
context.getManageClient().putJson(forestManager.getPropertiesPath(forestName), json);
130+
logger.info(format("Finished creating forest replicas for primary forest %s", forestName));
131+
}
132+
}
133+
134+
/**
135+
* Per #389, the list of replicas needs to be calculated for all forests at once so that ForestBuilder produces the
136+
* correct results.
137+
*
138+
* @param databaseName
139+
* @param context
140+
* @return
141+
*/
142+
protected List<Forest> determineForestsNeedingReplicas(String databaseName, CommandContext context) {
111143
ForestManager forestManager = new ForestManager(context.getManageClient());
112144
DatabaseManager dbMgr = new DatabaseManager(context.getManageClient());
113145
API api = new API(context.getManageClient());
114146
ResourceMapper resourceMapper = new DefaultResourceMapper(api);
115147

148+
List<Forest> forestsNeedingReplicas = new ArrayList<>();
149+
116150
for (String forestName : dbMgr.getForestNames(databaseName)) {
117151
logger.info(format("Checking the status of forest %s to determine if it is a primary forest and whether or not it has replicas already.", forestName));
118152
ForestStatus status = forestManager.getForestStatus(forestName);
@@ -125,25 +159,12 @@ protected void configureDatabaseReplicaForests(String databaseName, int replicaC
125159
continue;
126160
}
127161

128-
logger.info(format("Creating forest replicas for primary forest %s", forestName));
129-
130162
String forestJson = forestManager.getPropertiesAsJson(forestName);
131163
Forest forest = resourceMapper.readResource(forestJson, Forest.class);
132-
133-
List<String> selectedHostNames = getHostNamesForDatabaseForests(databaseName, hostNames, context);
134-
135-
ForestBuilder forestBuilder = new ForestBuilder();
136-
ForestPlan forestPlan = new ForestPlan(databaseName, selectedHostNames).withReplicaCount(replicaCount);
137-
List<String> dataDirectories = forestBuilder.determineDataDirectories(databaseName, context.getAppConfig());
138-
forestBuilder.addReplicasToForests(Arrays.asList(forest), forestPlan, context.getAppConfig(), dataDirectories);
139-
140-
Forest forestWithOnlyReplicas = new Forest();
141-
forestWithOnlyReplicas.setForestReplica(forest.getForestReplica());
142-
143-
String json = forestWithOnlyReplicas.getJson();
144-
context.getManageClient().putJson(forestManager.getPropertiesPath(forestName), json);
145-
logger.info(format("Finished creating forest replicas for primary forest %s", forestName));
164+
forestsNeedingReplicas.add(forest);
146165
}
166+
167+
return forestsNeedingReplicas;
147168
}
148169

149170
/**

src/test/java/com/marklogic/appdeployer/command/forests/BuildForestReplicaTest.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,29 @@ public class BuildForestReplicaTest extends Assert {
1414

1515
private ForestBuilder builder = new ForestBuilder();
1616

17+
@Test
18+
public void multipleForestsOnEachHost() {
19+
AppConfig appConfig = newAppConfig("mlForestsPerHost", "db,2");
20+
21+
List<Forest> forests = builder.buildForests(
22+
new ForestPlan("db", "host1", "host2", "host3").withReplicaCount(1), appConfig);
23+
24+
assertEquals("host1", forests.get(0).getHost());
25+
assertEquals("host2", forests.get(0).getForestReplica().get(0).getHost());
26+
assertEquals("host1", forests.get(1).getHost());
27+
assertEquals("host3", forests.get(1).getForestReplica().get(0).getHost());
28+
29+
assertEquals("host2", forests.get(2).getHost());
30+
assertEquals("host3", forests.get(2).getForestReplica().get(0).getHost());
31+
assertEquals("host2", forests.get(3).getHost());
32+
assertEquals("host1", forests.get(3).getForestReplica().get(0).getHost());
33+
34+
assertEquals("host3", forests.get(4).getHost());
35+
assertEquals("host1", forests.get(4).getForestReplica().get(0).getHost());
36+
assertEquals("host3", forests.get(5).getHost());
37+
assertEquals("host2", forests.get(5).getForestReplica().get(0).getHost());
38+
}
39+
1740
@Test
1841
public void customNamingStrategyWithDistributedStrategy() {
1942
AppConfig appConfig = newAppConfig("mlForestsPerHost", "my-database,2");

src/test/java/com/marklogic/appdeployer/command/forests/ConfigureForestReplicasDebug.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ public static void main(String[] args) {
2323

2424
ManageConfig config = new ManageConfig(host, 8002, "admin", password);
2525
ManageClient manageClient = new ManageClient(config);
26-
AppConfig appConfig = new AppConfig();
2726

27+
AppConfig appConfig = new AppConfig();
2828
Map<String, Integer> map = new HashMap<>();
29-
map.put(dbName, 1);
29+
map.put(dbName, 2);
3030
appConfig.setDatabaseNamesAndReplicaCounts(map);
3131

3232
List<String> hostNames = new HostManager(manageClient).getHostNames();
@@ -52,16 +52,13 @@ public static void main(String[] args) {
5252
ddc.setDatabaseName(dbName);
5353

5454
ConfigureForestReplicasCommand cfrc = new ConfigureForestReplicasCommand();
55-
Map<String, Integer> replicaCounts = new HashMap<>();
56-
replicaCounts.put(dbName, 1);
57-
appConfig.setDatabaseNamesAndReplicaCounts(replicaCounts);
5855

5956
// Deploy the database, and then configure replicas
6057
ddc.execute(context);
6158
cfrc.execute(context);
6259

6360
// Deploy again to make sure there are no errors
64-
//cfrc.execute(context);
61+
cfrc.execute(context);
6562

6663
// Then delete the replicas, and then undeploy the database
6764
cfrc.undo(context);

0 commit comments

Comments
 (0)