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

Commit 4299385

Browse files
author
Rob Rudin
committed
New Export API
1 parent 942e0c3 commit 4299385

File tree

10 files changed

+331
-0
lines changed

10 files changed

+331
-0
lines changed
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package com.marklogic.appdeployer.export;
2+
3+
import com.marklogic.mgmt.ManageClient;
4+
import com.marklogic.mgmt.ResourceManager;
5+
import org.springframework.util.FileCopyUtils;
6+
7+
import java.io.File;
8+
import java.io.IOException;
9+
import java.util.ArrayList;
10+
import java.util.List;
11+
12+
/**
13+
* Can use this as a parent class when exporting a resource that can be referred to via a single name, and when that
14+
* name makes sense to use as the name of the file that's exported.
15+
*/
16+
public abstract class AbstractNamedResourceExporter extends AbstractResourceExporter {
17+
18+
private String[] resourceNames;
19+
20+
protected AbstractNamedResourceExporter(ManageClient manageClient, String... resourceNames) {
21+
super(manageClient);
22+
this.resourceNames = resourceNames;
23+
}
24+
25+
protected abstract ResourceManager newResourceManager(ManageClient manageClient);
26+
27+
protected abstract File getResourceDirectory(File baseDir);
28+
29+
@Override
30+
public List<File> exportResources(File baseDir) {
31+
ResourceManager mgr = newResourceManager(getManageClient());
32+
File resourceDir = getResourceDirectory(baseDir);
33+
resourceDir.mkdirs();
34+
List<File> files = new ArrayList<>();
35+
for (String resourceName : resourceNames) {
36+
File f = exportToFile(mgr, resourceName, resourceDir);
37+
if (f != null) {
38+
files.add(f);
39+
}
40+
}
41+
return files;
42+
}
43+
44+
protected File exportToFile(ResourceManager mgr, String resourceName, File resourceDir) {
45+
File f = null;
46+
try {
47+
if (isFormatXml()) {
48+
f = exportToXml(mgr, resourceName, resourceDir);
49+
} else {
50+
f = exportToJson(mgr, resourceName, resourceDir);
51+
}
52+
} catch (IOException ex) {
53+
logger.warn(format("Unable to export resource with name %s to resource directory %s, cause: %s",
54+
resourceName, resourceDir.getAbsolutePath(), ex.getMessage()), ex);
55+
}
56+
return f;
57+
}
58+
59+
protected File exportToXml(ResourceManager mgr, String resourceName, File resourceDir) throws IOException {
60+
String xml = mgr.getPropertiesAsXml(resourceName).getPrettyXml();
61+
File f = new File(resourceDir, resourceName + ".xml");
62+
logWritingFile(resourceName, f);
63+
FileCopyUtils.copy(xml.getBytes(), f);
64+
return f;
65+
}
66+
67+
protected File exportToJson(ResourceManager mgr, String resourceName, File resourceDir) throws IOException {
68+
String json = mgr.getPropertiesAsJson(resourceName);
69+
File f = new File(resourceDir, resourceName + ".json");
70+
logWritingFile(resourceName, f);
71+
FileCopyUtils.copy(json.getBytes(), f);
72+
return f;
73+
}
74+
75+
protected void logWritingFile(String resourceName, File file) {
76+
if (logger.isInfoEnabled()) {
77+
logger.info(format("Exporting resource %s to file %s", resourceName, file.getAbsolutePath()));
78+
}
79+
}
80+
81+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.marklogic.appdeployer.export;
2+
3+
import com.marklogic.client.helper.LoggingObject;
4+
import com.marklogic.mgmt.ManageClient;
5+
6+
/**
7+
* Base class that provides a few conveniences for implementing ResourceExporter.
8+
*
9+
* TODO Should be able to add TaskExecutor support to allow for parallelizing requests to the Management API to
10+
* export resources.
11+
*/
12+
public abstract class AbstractResourceExporter extends LoggingObject implements ResourceExporter {
13+
14+
private ManageClient manageClient;
15+
private String format = "xml";
16+
17+
protected AbstractResourceExporter(ManageClient manageClient) {
18+
this.manageClient = manageClient;
19+
}
20+
21+
protected boolean isFormatXml() {
22+
return "xml".equalsIgnoreCase(format);
23+
}
24+
25+
public String getFormat() {
26+
return format;
27+
}
28+
29+
public void setFormat(String format) {
30+
this.format = format;
31+
}
32+
33+
public ManageClient getManageClient() {
34+
return manageClient;
35+
}
36+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package com.marklogic.appdeployer.export;
2+
3+
import com.marklogic.mgmt.ManageClient;
4+
5+
import java.io.File;
6+
import java.util.ArrayList;
7+
import java.util.Arrays;
8+
import java.util.List;
9+
10+
/**
11+
* Lets you combine many instances of ResourceExporter and invoke them all at once (could parallelize this in the
12+
* future).
13+
*/
14+
public class CompositeResourceExporter extends AbstractResourceExporter {
15+
16+
private List<ResourceExporter> resourceExporters;
17+
private boolean overrideFormatOnExporters = true;
18+
19+
public CompositeResourceExporter(ManageClient manageClient, ResourceExporter... resourceExporters) {
20+
super(manageClient);
21+
this.resourceExporters = new ArrayList<>();
22+
for (ResourceExporter exporter : resourceExporters) {
23+
this.resourceExporters.add(exporter);
24+
}
25+
}
26+
27+
public void add(ResourceExporter exporter) {
28+
this.resourceExporters.add(exporter);
29+
}
30+
31+
@Override
32+
public List<File> exportResources(File baseDir) {
33+
List<File> files = new ArrayList<>();
34+
for (ResourceExporter exporter : resourceExporters) {
35+
if (overrideFormatOnExporters && exporter instanceof AbstractResourceExporter) {
36+
((AbstractResourceExporter) exporter).setFormat(getFormat());
37+
}
38+
files.addAll(exporter.exportResources(baseDir));
39+
}
40+
return files;
41+
}
42+
43+
public boolean isOverrideFormatOnExporters() {
44+
return overrideFormatOnExporters;
45+
}
46+
47+
public void setOverrideFormatOnExporters(boolean overrideFormatOnExporters) {
48+
this.overrideFormatOnExporters = overrideFormatOnExporters;
49+
}
50+
51+
public List<ResourceExporter> getResourceExporters() {
52+
return resourceExporters;
53+
}
54+
55+
public void setResourceExporters(List<ResourceExporter> resourceExporters) {
56+
this.resourceExporters = resourceExporters;
57+
}
58+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.marklogic.appdeployer.export;
2+
3+
import com.marklogic.appdeployer.export.security.RoleExporter;
4+
import com.marklogic.appdeployer.export.security.UserExporter;
5+
import com.marklogic.mgmt.ManageClient;
6+
7+
import java.io.File;
8+
import java.util.List;
9+
10+
/**
11+
* Intent is to provide a fluent-ish way of composing comands for exporting resources.
12+
*/
13+
public class Exporter {
14+
15+
private CompositeResourceExporter compositeExporter;
16+
private ManageClient manageClient;
17+
18+
public static Exporter client(ManageClient manageClient) {
19+
return new Exporter(manageClient);
20+
}
21+
22+
public Exporter(ManageClient manageClient) {
23+
this.manageClient = manageClient;
24+
compositeExporter = new CompositeResourceExporter(manageClient);
25+
}
26+
27+
public Exporter format(String xmlOrJson) {
28+
compositeExporter.setFormat(xmlOrJson);
29+
return this;
30+
}
31+
32+
public List<File> export(File baseDir) {
33+
return compositeExporter.exportResources(baseDir);
34+
}
35+
36+
public Exporter users(String... usernames) {
37+
compositeExporter.add(new UserExporter(manageClient, usernames));
38+
return this;
39+
}
40+
41+
public Exporter roles(String... roleNames) {
42+
compositeExporter.add(new RoleExporter(manageClient, roleNames));
43+
return this;
44+
}
45+
46+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.marklogic.appdeployer.export;
2+
3+
import java.io.File;
4+
import java.util.List;
5+
6+
/**
7+
* Interface for exporting one or more MarkLogic resources via the Management API to disk.
8+
*/
9+
public interface ResourceExporter {
10+
11+
/**
12+
* @param baseDir
13+
* @return a list of Files, one for each resource that was exported; expectation is this will mostly be for reporting
14+
* reasons
15+
*/
16+
List<File> exportResources(File baseDir);
17+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.marklogic.appdeployer.export.security;
2+
3+
import com.marklogic.appdeployer.ConfigDir;
4+
import com.marklogic.appdeployer.export.AbstractNamedResourceExporter;
5+
import com.marklogic.mgmt.ManageClient;
6+
import com.marklogic.mgmt.ResourceManager;
7+
import com.marklogic.mgmt.security.RoleManager;
8+
9+
import java.io.File;
10+
11+
public class RoleExporter extends AbstractNamedResourceExporter {
12+
13+
public RoleExporter(ManageClient manageClient, String... usernames) {
14+
super(manageClient, usernames);
15+
}
16+
17+
@Override
18+
protected ResourceManager newResourceManager(ManageClient manageClient) {
19+
return new RoleManager(manageClient);
20+
}
21+
22+
@Override
23+
protected File getResourceDirectory(File baseDir) {
24+
return new File(new ConfigDir(baseDir).getSecurityDir(), "roles");
25+
}
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.marklogic.appdeployer.export.security;
2+
3+
import com.marklogic.appdeployer.ConfigDir;
4+
import com.marklogic.appdeployer.export.AbstractNamedResourceExporter;
5+
import com.marklogic.mgmt.ManageClient;
6+
import com.marklogic.mgmt.ResourceManager;
7+
import com.marklogic.mgmt.security.UserManager;
8+
9+
import java.io.File;
10+
11+
public class UserExporter extends AbstractNamedResourceExporter {
12+
13+
public UserExporter(ManageClient manageClient, String... usernames) {
14+
super(manageClient, usernames);
15+
}
16+
17+
@Override
18+
protected ResourceManager newResourceManager(ManageClient manageClient) {
19+
return new UserManager(manageClient);
20+
}
21+
22+
@Override
23+
protected File getResourceDirectory(File baseDir) {
24+
return new File(new ConfigDir(baseDir).getSecurityDir(), "users");
25+
}
26+
}

src/main/java/com/marklogic/mgmt/AbstractResourceManager.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ public String getAsJson(String resourceNameOrId, String... resourceUrlParams) {
6060
return manageClient.getJson(path);
6161
}
6262

63+
public String getPropertiesAsJson(String resourceNameOrId, String... resourceUrlParams) {
64+
String path = appendParamsAndValuesToPath(getPropertiesPath(resourceNameOrId, resourceUrlParams));
65+
return useAdminUser() ? manageClient.getJsonAsAdmin(path) : manageClient.getJson(path);
66+
}
67+
6368
/**
6469
* Determines whether to create a new resource or update an existing one based on the contents of the payload.
6570
*/

src/main/java/com/marklogic/mgmt/ResourceManager.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,12 @@ public interface ResourceManager {
7777
* @return
7878
*/
7979
public Fragment getPropertiesAsXml(String resourceNameOrId, String... resourceUrlParams);
80+
81+
/**
82+
* @param resourceNameOrId
83+
* @param resourceUrlParams
84+
* @return
85+
*/
86+
public String getPropertiesAsJson(String resourceNameOrId, String... resourceUrlParams);
87+
8088
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.marklogic.appdeployer.export;
2+
3+
import com.marklogic.appdeployer.AbstractAppDeployerTest;
4+
import org.junit.Test;
5+
6+
import java.io.File;
7+
import java.util.List;
8+
9+
public class ExportTest extends AbstractAppDeployerTest {
10+
11+
@Test
12+
public void test() throws Exception {
13+
14+
// Define the directory to export to
15+
File baseDir = new File("build/export-test");
16+
baseDir.mkdirs();
17+
18+
List<File> exportedFiles =
19+
Exporter.client(manageClient)
20+
.users("admin", "nobody")
21+
.roles("admin", "rest-admin", "rest-reader")
22+
.format("xml")
23+
.export(baseDir);
24+
25+
// Export!
26+
System.out.println(exportedFiles);
27+
}
28+
}

0 commit comments

Comments
 (0)