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

Commit ee8bb18

Browse files
committed
#106 Can now create custom forests
1 parent dfb31d7 commit ee8bb18

File tree

15 files changed

+180
-42
lines changed

15 files changed

+180
-42
lines changed

.editorconfig

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# http://editorconfig.org
2+
root = true
3+
4+
[*]
5+
indent_style = tab
6+
indent_size = 2
7+
end_of_line = lf
8+
charset = utf-8
9+
trim_trailing_whitespace = true
10+
insert_final_newline = true
11+
12+
[*.md]
13+
trim_trailing_whitespace = false
14+
15+
[*.java]
16+
indent_size = 4

src/main/java/com/marklogic/appdeployer/command/AbstractCommand.java

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public Integer getExecuteSortOrder() {
3737
/**
3838
* Convenience method for setting the names of files to ignore when reading resources from a directory. Will
3939
* preserve any filenames already being ignored on the underlying FilenameFilter.
40-
*
40+
*
4141
* @param filenames
4242
*/
4343
public void setFilenamesToIgnore(String... filenames) {
@@ -59,7 +59,7 @@ public void setFilenamesToIgnore(String... filenames) {
5959

6060
/**
6161
* Simplifies reading the contents of a File into a String.
62-
*
62+
*
6363
* @param f
6464
* @return
6565
*/
@@ -73,17 +73,29 @@ protected String copyFileToString(File f) {
7373
}
7474
}
7575

76+
/**
77+
* Convenience function for reading the file into a string and replace tokens as well. Assumes this is not
78+
* for a test-only resource.
79+
*
80+
* @param f
81+
* @param context
82+
* @return
83+
*/
84+
protected String copyFileToString(File f, CommandContext context) {
85+
String str = copyFileToString(f);
86+
return str != null ? tokenReplacer.replaceTokens(str, context.getAppConfig(), false) : str;
87+
}
88+
7689
/**
7790
* Provides a basic implementation for saving a resource defined in a File, including replacing tokens.
78-
*
91+
*
7992
* @param mgr
8093
* @param context
8194
* @param f
8295
* @return
8396
*/
8497
protected SaveReceipt saveResource(ResourceManager mgr, CommandContext context, File f) {
85-
String payload = copyFileToString(f);
86-
payload = tokenReplacer.replaceTokens(payload, context.getAppConfig(), false);
98+
String payload = copyFileToString(f, context);
8799
SaveReceipt receipt = mgr.save(payload);
88100
if (storeResourceIdsAsCustomTokens) {
89101
storeTokenForResourceId(receipt, context);
@@ -95,7 +107,7 @@ protected SaveReceipt saveResource(ResourceManager mgr, CommandContext context,
95107
* Any resource that may be referenced by its ID by another resource will most likely need its ID stored as a custom
96108
* token so that it can be referenced by the other resource. To enable this, the subclass should set
97109
* storeResourceIdAsCustomToken to true.
98-
*
110+
*
99111
* @param receipt
100112
* @param context
101113
*/

src/main/java/com/marklogic/appdeployer/command/AbstractResourceCommand.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public void execute(CommandContext context) {
4141

4242
/**
4343
* Subclasses can override this to add functionality after a resource has been saved.
44-
*
44+
*
4545
* @param mgr
4646
* @param context
4747
* @param resourceFile
@@ -77,13 +77,13 @@ public void undo(CommandContext context) {
7777
* delete the resource. This has been necessary when deleting two app servers in a row - for some reason, the 2nd
7878
* delete will intermittently fail with a connection reset error, but the app server is in fact deleted
7979
* successfully.
80-
*
80+
*
8181
* @param mgr
8282
* @param context
8383
* @param f
8484
*/
8585
protected void deleteResource(final ResourceManager mgr, CommandContext context, File f) {
86-
final String payload = tokenReplacer.replaceTokens(copyFileToString(f), context.getAppConfig(), false);
86+
final String payload = copyFileToString(f, context);
8787
try {
8888
if (restartAfterDelete) {
8989
context.getAdminManager().invokeActionRequiringRestart(new ActionRequiringRestart() {

src/main/java/com/marklogic/appdeployer/command/alert/DeployAlertRulesCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ protected void deployRulesInDirectory(File dir, CommandContext context) {
4444
* parse its contents.
4545
*/
4646
for (File f : listFilesInDirectory(dir)) {
47-
String payload = copyFileToString(f);
47+
String payload = copyFileToString(f, context);
4848
String actionName = payloadParser.getPayloadFieldValue(payload, "action-name");
4949
AlertRuleManager mgr = new AlertRuleManager(context.getManageClient(), dbName, configUri, actionName);
5050
saveResource(mgr, context, f);

src/main/java/com/marklogic/appdeployer/command/cpf/AbstractCpfResourceCommand.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ public void execute(CommandContext context) {
2020
if (dir.exists()) {
2121
AbstractCpfResourceManager mgr = getResourceManager(context);
2222
for (File f : listFilesInDirectory(dir)) {
23-
String payload = copyFileToString(f);
24-
payload = tokenReplacer.replaceTokens(payload, config, false);
23+
String payload = copyFileToString(f, context);
2524
mgr.save(config.getTriggersDatabaseName(), payload);
2625
}
2726
}

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
* Command for configuring - i.e. creating and setting - replica forests for existing databases and/or primary forests.
1717
* It's normally easier to just specify the databases that you want to configure forest replicas for, but this command
1818
* does provide the ability to configure replicas for specific forests.
19-
*
19+
*
2020
* Very useful for the out-of-the-box forests such as Security, Schemas, App-Services, and Meters, which normally need
2121
* replicas for failover in a cluster.
2222
*/
@@ -38,7 +38,7 @@ public ConfigureForestReplicasCommand() {
3838
/**
3939
* Allows for the map of database names and counts to be configured as a comma-delimited string of the form:
4040
* "dbName,replicaCount,dbName,replicaCount,etc".
41-
*
41+
*
4242
* @param str
4343
*/
4444
public void setDatabaseNamesAndReplicaCountsAsString(String str) {
@@ -96,7 +96,7 @@ public void undo(CommandContext context) {
9696
if (str != null) {
9797
setDatabaseNamesAndReplicaCountsAsString(str);
9898
}
99-
99+
100100
DatabaseManager dbMgr = new DatabaseManager(context.getManageClient());
101101
ForestManager forestMgr = new ForestManager(context.getManageClient());
102102

@@ -132,7 +132,7 @@ protected void deleteReplicas(String forestName, ForestManager forestMgr) {
132132
* For the given database, find all of its primary forests. Then for each primary forest, just call
133133
* configureReplicaForests? And that should be smart enough to say - if the primary forest already has replicas,
134134
* then don't do anything.
135-
*
135+
*
136136
* @param databaseName
137137
* @param replicaCount
138138
* @param hostIds
@@ -151,7 +151,7 @@ protected void configureDatabaseReplicaForests(String databaseName, int replicaC
151151
/**
152152
* Creates forests as needed (they may already exists) and then sets those forests as the replicas for the given
153153
* primaryForestName.
154-
*
154+
*
155155
* @param forestIdOrName
156156
* @param replicaCount
157157
* @param hostIds
@@ -178,7 +178,7 @@ protected void configureReplicaForests(String forestIdOrName, int replicaCount,
178178
if (!hostId.equals(primaryForestHostId)) {
179179
for (int i = 0; i < replicaCount; i++) {
180180
String name = forestIdOrName + "-" + resourceCounter;
181-
forestMgr.createForestWithName(name, hostId);
181+
forestMgr.createJsonForestWithName(name, hostId);
182182
replicaNamesAndHostIds.put(name, hostId);
183183
resourceCounter++;
184184
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.marklogic.appdeployer.command.forests;
2+
3+
import com.marklogic.appdeployer.command.AbstractCommand;
4+
import com.marklogic.appdeployer.command.CommandContext;
5+
import com.marklogic.appdeployer.command.SortOrderConstants;
6+
import com.marklogic.mgmt.forests.ForestManager;
7+
8+
import java.io.File;
9+
10+
/**
11+
* Use this command when you want precise control over the forests that are created for a database. It processes
12+
* each directory under ml-config/forests (the name of the directory does not matter, but it makes sense to name
13+
* it after the database that the forests belong to), and each file in a directory can have a single forest object
14+
* or an array of forest objects.
15+
*/
16+
public class DeployCustomForestsCommand extends AbstractCommand {
17+
18+
public DeployCustomForestsCommand() {
19+
setExecuteSortOrder(SortOrderConstants.DEPLOY_FORESTS);
20+
}
21+
22+
@Override
23+
public void execute(CommandContext context) {
24+
File dir = new File(context.getAppConfig().getConfigDir().getBaseDir(), "forests");
25+
for (File f : dir.listFiles()) {
26+
if (f.isDirectory()) {
27+
processDirectory(f, context);
28+
}
29+
}
30+
}
31+
32+
protected void processDirectory(File dir, CommandContext context) {
33+
ForestManager mgr = new ForestManager(context.getManageClient());
34+
for (File f : listFilesInDirectory(dir)) {
35+
String payload = copyFileToString(f, context);
36+
mgr.saveJsonForests(payload);
37+
}
38+
}
39+
}

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
import com.marklogic.mgmt.hosts.HostManager;
1616

1717
/**
18+
* This command is for a simple use case where all the forests created for a database have the same structure,
19+
* but possibly exist on different forests. For more precise control over how forests are created, please see
20+
* DeployCustomForestsCommand.
21+
*
1822
* Doesn't yet support deleting forests - currently assumed that this will be done by deleting a database.
1923
*/
2024
public class DeployForestsCommand extends AbstractCommand {
@@ -148,4 +152,4 @@ public boolean isCreateForestsOnEachHost() {
148152
public void setCreateForestsOnEachHost(boolean createForestsOnEachHost) {
149153
this.createForestsOnEachHost = createForestsOnEachHost;
150154
}
151-
}
155+
}

src/main/java/com/marklogic/appdeployer/command/security/DeployCertificateAuthoritiesCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public void execute(CommandContext context) {
2525
if (logger.isInfoEnabled()) {
2626
logger.info("Creating certificate authority from file: " + f.getAbsolutePath());
2727
}
28-
String payload = copyFileToString(f);
28+
String payload = copyFileToString(f, context);
2929
ResponseEntity<String> response = mgr.create(payload);
3030
if (logger.isInfoEnabled()) {
3131
logger.info("Created certificate authority, location: " + response.getHeaders().getLocation());

src/main/java/com/marklogic/mgmt/forests/ForestManager.java

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package com.marklogic.mgmt.forests;
22

33
import java.util.HashMap;
4+
import java.util.Iterator;
45
import java.util.List;
56
import java.util.Map;
67

8+
import com.fasterxml.jackson.databind.JsonNode;
79
import com.marklogic.mgmt.AbstractResourceManager;
810
import com.marklogic.mgmt.ManageClient;
911
import com.marklogic.rest.util.Fragment;
@@ -20,15 +22,14 @@ public class ForestManager extends AbstractResourceManager {
2022

2123
public ForestManager(ManageClient client) {
2224
super(client);
23-
setUpdateAllowed(false);
2425
}
2526

26-
public void createForestWithName(String name, String host) {
27+
public void createJsonForestWithName(String name, String host) {
2728
if (forestExists(name)) {
2829
logger.info(format("Forest already exists with name, so not creating: %s", name));
2930
} else {
3031
logger.info(format("Creating forest %s on host %s", name, host));
31-
createForest(format("{\"forest-name\":\"%s\", \"host\":\"%s\"}", name, host));
32+
createJsonForest(format("{\"forest-name\":\"%s\", \"host\":\"%s\"}", name, host));
3233
logger.info(format("Created forest %s on host %s", name, host));
3334
}
3435
}
@@ -43,7 +44,24 @@ public void delete(String nameOrId, String level) {
4344
}
4445
}
4546

46-
public void createForest(String json) {
47+
/**
48+
* Supports either an array of JSON objects or a single JSON object.
49+
*
50+
* @param json
51+
*/
52+
public void saveJsonForests(String json) {
53+
JsonNode node = super.payloadParser.parseJson(json);
54+
if (node.isArray()) {
55+
Iterator<JsonNode> iter = node.iterator();
56+
while (iter.hasNext()) {
57+
save(iter.next().toString());
58+
}
59+
} else {
60+
save(json);
61+
}
62+
}
63+
64+
public void createJsonForest(String json) {
4765
getManageClient().postJson("/manage/v2/forests", json);
4866
}
4967

@@ -103,7 +121,7 @@ public void setReplicas(String forestIdOrName, Map<String, String> replicaNamesA
103121
/**
104122
* Convenience method for detaching a forest from any replicas it has; this is often used before deleting those
105123
* replicas
106-
*
124+
*
107125
* @param forestIdOrName
108126
*/
109127
public void setReplicasToNone(String forestIdOrName) {
@@ -112,7 +130,7 @@ public void setReplicasToNone(String forestIdOrName) {
112130

113131
/**
114132
* Returns a list of IDs for each replica forest for the given forest ID or name.
115-
*
133+
*
116134
* @param forestIdOrName
117135
* @return
118136
*/
@@ -124,7 +142,7 @@ public List<String> getReplicaIds(String forestIdOrName) {
124142

125143
/**
126144
* Deletes (with a level of "full") all replicas for the given forest.
127-
*
145+
*
128146
* @param forestIdOrName
129147
*/
130148
public void deleteReplicas(String forestIdOrName) {

0 commit comments

Comments
 (0)