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

Commit c976756

Browse files
committed
#271 Can now deploy configuration packages
1 parent 4fcca13 commit c976756

File tree

8 files changed

+205
-33
lines changed

8 files changed

+205
-33
lines changed

src/main/java/com/marklogic/appdeployer/ConfigDir.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ public File getRestApiServerFile() {
7272
return new File(getServersDir(), "rest-api-server.json");
7373
}
7474

75+
public File getConfigurationsDir() {
76+
return new File(baseDir, "configurations");
77+
}
78+
7579
public File getSecurityDir() {
7680
return new File(baseDir, "security");
7781
}

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22

33
import com.marklogic.client.ext.helper.LoggingObject;
44
import com.marklogic.mgmt.PayloadParser;
5+
import com.marklogic.mgmt.admin.AdminManager;
56
import com.marklogic.mgmt.resource.ResourceManager;
67
import com.marklogic.mgmt.SaveReceipt;
8+
import org.springframework.http.HttpHeaders;
9+
import org.springframework.http.ResponseEntity;
710
import org.springframework.util.FileCopyUtils;
811

912
import java.io.File;
@@ -154,6 +157,38 @@ protected SaveReceipt saveResource(ResourceManager mgr, CommandContext context,
154157
return receipt;
155158
}
156159

160+
/**
161+
* Subclasses can override this to add functionality after a resource has been saved.
162+
*
163+
* Starting in version 3.0 of ml-app-deployer, this will always check if the Location header is
164+
* /admin/v1/timestamp, and if so, it will wait for ML to restart.
165+
*
166+
* @param mgr
167+
* @param context
168+
* @param resourceFile
169+
* @param receipt
170+
*/
171+
protected void afterResourceSaved(ResourceManager mgr, CommandContext context, File resourceFile, SaveReceipt receipt) {
172+
if (receipt == null) {
173+
return;
174+
}
175+
ResponseEntity<String> response = receipt.getResponse();
176+
if (response != null) {
177+
HttpHeaders headers = response.getHeaders();
178+
if (headers != null) {
179+
URI uri = headers.getLocation();
180+
if (uri != null && "/admin/v1/timestamp".equals(uri.getPath())) {
181+
AdminManager adminManager = context.getAdminManager();
182+
if (adminManager != null) {
183+
adminManager.waitForRestart();
184+
} else {
185+
logger.warn("Location header indicates ML is restarting, but no AdminManager available to support waiting for a restart");
186+
}
187+
}
188+
}
189+
}
190+
}
191+
157192
/**
158193
* Allow subclass to override this in order to fiddle with the payload before it's saved; called by saveResource.
159194
*

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

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -97,39 +97,6 @@ protected File[] listFilesInDirectory(File resourceDir, CommandContext context)
9797
return listFilesInDirectory(resourceDir);
9898
}
9999

100-
/**
101-
* Subclasses can override this to add functionality after a resource has been saved.
102-
*
103-
* Starting in version 3.0 of ml-app-deployer, this will always check if the Location header is
104-
* /admin/v1/timestamp, and if so, it will wait for ML to restart.
105-
*
106-
* @param mgr
107-
* @param context
108-
* @param resourceFile
109-
* @param receipt
110-
*/
111-
protected void afterResourceSaved(ResourceManager mgr, CommandContext context, File resourceFile,
112-
SaveReceipt receipt) {
113-
if (receipt == null) {
114-
return;
115-
}
116-
ResponseEntity<String> response = receipt.getResponse();
117-
if (response != null) {
118-
HttpHeaders headers = response.getHeaders();
119-
if (headers != null) {
120-
URI uri = headers.getLocation();
121-
if (uri != null && "/admin/v1/timestamp".equals(uri.getPath())) {
122-
AdminManager adminManager = context.getAdminManager();
123-
if (adminManager != null) {
124-
adminManager.waitForRestart();
125-
} else {
126-
logger.warn("Location header indicates ML is restarting, but no AdminManager available to support waiting for a restart");
127-
}
128-
}
129-
}
130-
}
131-
}
132-
133100
@Override
134101
public void undo(CommandContext context) {
135102
if (deleteResourcesOnUndo) {
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.marklogic.appdeployer.command.cma;
2+
3+
import com.marklogic.appdeployer.ConfigDir;
4+
import com.marklogic.appdeployer.command.AbstractCommand;
5+
import com.marklogic.appdeployer.command.CommandContext;
6+
import com.marklogic.mgmt.SaveReceipt;
7+
import com.marklogic.mgmt.cma.ConfigurationManager;
8+
9+
import java.io.File;
10+
11+
/**
12+
* The /manage/v3 docs indicate that zips can be uploaded, but it's not clear what the format of those zips should be.
13+
* So for now, this just supports JSON and XML, which seem like the most likely formats to use.
14+
*/
15+
public class DeployConfigurationsCommand extends AbstractCommand {
16+
17+
@Override
18+
public void execute(CommandContext context) {
19+
ConfigurationManager mgr = new ConfigurationManager(context.getManageClient());
20+
21+
for (ConfigDir configDir : context.getAppConfig().getConfigDirs()) {
22+
File dir = configDir.getConfigurationsDir();
23+
if (dir != null && dir.exists()) {
24+
if (logger.isInfoEnabled()) {
25+
logger.info("Processing files in directory: " + dir.getAbsolutePath());
26+
}
27+
for (File f : super.listFilesInDirectory(dir)) {
28+
if (logger.isInfoEnabled()) {
29+
logger.info("Processing file: " + f.getAbsolutePath());
30+
}
31+
String payload = copyFileToString(f, context);
32+
payload = adjustPayloadBeforeSavingResource(null, context, f, payload);
33+
SaveReceipt receipt = mgr.save(payload);
34+
afterResourceSaved(null, context, f, receipt);
35+
}
36+
} else {
37+
logResourceDirectoryNotFound(dir);
38+
}
39+
}
40+
}
41+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.marklogic.mgmt.cma;
2+
3+
import com.marklogic.mgmt.AbstractManager;
4+
import com.marklogic.mgmt.ManageClient;
5+
import com.marklogic.mgmt.SaveReceipt;
6+
import org.springframework.http.ResponseEntity;
7+
8+
/**
9+
* This doesn't extend AbstractResourceManager because a configuration isn't really a resource, it's a collection of
10+
* resources.
11+
*
12+
* Currently only supports JSON and XML configuration payloads. Not clear yet from the docs on what the format of a
13+
* zip should be. The docs also mention a bunch of request parameters, but the examples don't show what the purpose
14+
* of those are, so those aren't supported yet either.
15+
*/
16+
public class ConfigurationManager extends AbstractManager {
17+
18+
private ManageClient manageClient;
19+
20+
public ConfigurationManager(ManageClient manageClient) {
21+
this.manageClient = manageClient;
22+
}
23+
24+
public SaveReceipt save(String payload) {
25+
String configurationName = payloadParser.getPayloadFieldValue(payload, "name", false);
26+
if (configurationName == null) {
27+
configurationName = "with unknown name";
28+
}
29+
30+
if (logger.isInfoEnabled()) {
31+
logger.info("Applying configuration " + configurationName);
32+
}
33+
34+
final String path = "/manage/v3";
35+
ResponseEntity<String> response = postPayload(manageClient, path, payload);
36+
37+
if (logger.isInfoEnabled()) {
38+
logger.info("Applied configuration " + configurationName);
39+
}
40+
41+
return new SaveReceipt(null, payload, path, response);
42+
}
43+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.marklogic.appdeployer.command.cma;
2+
3+
import com.marklogic.appdeployer.AbstractAppDeployerTest;
4+
import com.marklogic.mgmt.resource.forests.ForestManager;
5+
import org.junit.Test;
6+
7+
import java.util.regex.Pattern;
8+
9+
public class DeployConfigurationsTest extends AbstractAppDeployerTest {
10+
11+
@Test
12+
public void deployJsonConfig() {
13+
setConfigBaseDir("sample-app/cma");
14+
appConfig.setResourceFilenamesIncludePattern(Pattern.compile(".*json"));
15+
initializeAppDeployer(new DeployConfigurationsCommand());
16+
deploySampleApp();
17+
18+
verifyForestsWereCreated();
19+
}
20+
21+
@Test
22+
public void deployXmlConfig() {
23+
setConfigBaseDir("sample-app/cma");
24+
appConfig.setResourceFilenamesIncludePattern(Pattern.compile(".*xml"));
25+
initializeAppDeployer(new DeployConfigurationsCommand());
26+
deploySampleApp();
27+
28+
verifyForestsWereCreated();
29+
}
30+
31+
private void verifyForestsWereCreated() {
32+
ForestManager forestManager = new ForestManager(manageClient);
33+
final String[] configForestNames = new String[]{"cma-test-f1", "cma-test-f2", "cma-test-f3"};
34+
try {
35+
for (String name : configForestNames) {
36+
assertTrue(forestManager.exists(name));
37+
}
38+
} finally {
39+
for (String name : configForestNames) {
40+
if (forestManager.exists(name)) {
41+
forestManager.delete(name, ForestManager.DELETE_LEVEL_FULL);
42+
}
43+
}
44+
}
45+
}
46+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"name": "ml-app-deployer-test-config",
3+
"config": [
4+
{
5+
"forest": [
6+
{
7+
"forest-name": "cma-test-f1"
8+
},
9+
{
10+
"forest-name": "cma-test-f2"
11+
},
12+
{
13+
"forest-name": "cma-test-f3"
14+
}
15+
]
16+
}
17+
]
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<configuration xmlns="http://marklogic.com/manage/config">
2+
<name>ml-app-deployer-test-config</name>
3+
<configs>
4+
<config>
5+
<forests>
6+
<forest>
7+
<forest-name>cma-test-f1</forest-name>
8+
</forest>
9+
<forest>
10+
<forest-name>cma-test-f2</forest-name>
11+
</forest>
12+
<forest>
13+
<forest-name>cma-test-f3</forest-name>
14+
</forest>
15+
</forests>
16+
</config>
17+
</configs>
18+
</configuration>

0 commit comments

Comments
 (0)