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

Commit 7eea938

Browse files
author
Rob Rudin
committed
Merge branch 'master' into dev
# Conflicts: # gradle.properties # src/main/java/com/marklogic/client/batch/RestBatchWriter.java # src/main/java/com/marklogic/client/modulesloader/impl/DefaultModulesLoader.java
2 parents 8f3f0f6 + 3a8a60b commit 7eea938

File tree

5 files changed

+87
-12
lines changed

5 files changed

+87
-12
lines changed

README.md

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,53 @@
33
ml-javaclient-util is a library of Java classes that provide some useful functionality on top of
44
the [MarkLogic Java Client API](http://docs.marklogic.com/guide/java). Those features include:
55

6-
- Support for loading any kind of module using the REST API
7-
- Support for automatically loading a new/modified module using the REST API
8-
- Basic integration with Spring via a Spring FactoryBean
6+
- Support for [loading modules via the REST API](https://github.com/rjrudin/ml-javaclient-util/tree/master/src/main/java/com/marklogic/client/modulesloader)
7+
- Basic integration with [Spring via a Spring FactoryBean](https://github.com/rjrudin/ml-javaclient-util/tree/master/src/main/java/com/marklogic/client/spring)
8+
- Library for [parallelizing batched writes](https://github.com/rjrudin/ml-javaclient-util/tree/master/src/main/java/com/marklogic/client/batch)
9+
- Spring-style [template/callback library for XCC](https://github.com/rjrudin/ml-javaclient-util/tree/master/src/main/java/com/marklogic/xcc/template)
10+
- Support for generating MarkLogic 9 [Entity Services modules](https://github.com/rjrudin/ml-javaclient-util/tree/master/src/main/java/com/marklogic/client/es)
11+
- Support for [importing/exporting qconsole workspaces] (https://github.com/rjrudin/ml-javaclient-util/tree/master/src/main/java/com/marklogic/client/qconsole)
12+
13+
This is a lower-level library that is primarily used via [ml-app-deployer](https://github.com/rjrudin/ml-app-deployer)
14+
and [ml-gradle](https://github.com/rjrudin/ml-gradle) and [ml-junit](https://github.com/rjrudin/ml-junit). But you can use it by itself too.
915

10-
This is a lower-level library that is primarily used via [ml-app-deployer](https://github.com/rjrudin/ml-app-deployer) and [ml-gradle](https://github.com/rjrudin/ml-gradle) and [ml-junit](https://github.com/rjrudin/ml-junit). But you can use it by itself too.
16+
### Loading Modules
1117

1218
Here's a sample of loading modules - though it's best to look at the aforementioned projects to see all the ways this can be done:
1319

1420
DatabaseClient client = DatabaseClientFactory.newClient(...); // Use the ML Java Client API
15-
RestApiAssetLoader assetLoader = new RestApiAssetLoader(client); // Can use XCC or the REST API to load asset modules
21+
XccAssetLoader assetLoader = new XccAssetLoader(client); // Can use XCC or the REST API to load asset modules
1622
DefaultModulesLoader modulesLoader = new DefaultModulesLoader(assetLoader);
1723
File modulesDir = new File("src/main/ml-modules");
1824
ModulesFinder modulesFinder = new DefaultModulesFinder(); // Allows for adjusting where modules are stored on a filesystem
1925
modulesLoader.loadModules(modulesDir, modulesFinder, client);
20-
26+
27+
### Parallelized batch writes
28+
29+
The [BatchWriter](https://github.com/rjrudin/ml-javaclient-util/tree/master/src/main/java/com/marklogic/client/batch) library
30+
was created primarily for applications using [marklogic-spring-batch](https://github.com/sastafford/marklogic-spring-batch). But
31+
it can be used in any environment. It provides the following features:
32+
33+
1. Uses Spring's [TaskExecutor library](https://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html) for parallelizing writes
34+
1. Supports writes via the REST API or XCC
35+
36+
Via Spring's TaskExecutor library, you can essentially throw an infinite number of documents at this interface. The library
37+
will default to a sensible implementation of [ThreadPoolTaskExecutor](http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/scheduling/concurrent/ThreadPoolTaskExecutor.html),
38+
but you can override that with any TaskExecutor implementation you like.
39+
40+
Once MarkLogic 9 is available, an implementation will be used that depends on the new Data Movement SDK, which is being
41+
added to the MarkLogic Java Client API.
42+
43+
Here's a sample using two DatabaseClient instances:
44+
45+
// This is all basic Java Client API stuff
46+
DatabaseClient client1 = DatabaseClientFactory.newClient("host1", ...);
47+
DatabaseClient client2 = DatabaseClientFactory.newClient("host2", ...);
48+
DocumentWriteOperation doc1 = new DocumentWriteOperationImpl("test1.xml", ...);
49+
DocumentWriteOperation doc2 = new DocumentWriteOperationImpl("test2.xml", ...);
50+
51+
// Here's how BatchWriter works
52+
BatchWriter writer = new RestBatchWriter(Arrays.asList(client1, client2));
53+
writer.initialize();
54+
writer.write(Arrays.asList(doc1, doc2));
55+
writer.waitForCompletion();

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
group=com.marklogic
22
javadocsDir=../gh-pages-marklogic-java/javadocs
3-
version=2.12.0
3+
version=2.12.1

src/main/java/com/marklogic/client/batch/RestBatchWriter.java

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package com.marklogic.client.batch;
22

33
import com.marklogic.client.DatabaseClient;
4+
import com.marklogic.client.document.DocumentManager;
45
import com.marklogic.client.document.DocumentWriteOperation;
56
import com.marklogic.client.document.DocumentWriteSet;
6-
import com.marklogic.client.document.GenericDocumentManager;
7+
import com.marklogic.client.document.ServerTransform;
78

89
import java.util.List;
910

@@ -17,6 +18,7 @@ public class RestBatchWriter extends BatchWriterSupport {
1718
private List<DatabaseClient> databaseClients;
1819
private int clientIndex = 0;
1920
private boolean releaseDatabaseClients = true;
21+
private ServerTransform serverTransform;
2022

2123
public RestBatchWriter(List<DatabaseClient> databaseClients) {
2224
this.databaseClients = databaseClients;
@@ -33,7 +35,7 @@ public void write(final List<? extends DocumentWriteOperation> items) {
3335
getTaskExecutor().execute(new Runnable() {
3436
@Override
3537
public void run() {
36-
GenericDocumentManager mgr = client.newDocumentManager();
38+
DocumentManager<?, ?> mgr = buildDocumentManager(client);
3739
DocumentWriteSet set = mgr.newWriteSet();
3840
for (DocumentWriteOperation item : items) {
3941
set.add(item);
@@ -42,14 +44,29 @@ public void run() {
4244
if (logger.isDebugEnabled()) {
4345
logger.debug("Writing " + count + " documents to MarkLogic");
4446
}
45-
mgr.write(set);
47+
if (serverTransform != null) {
48+
mgr.write(set, serverTransform);
49+
} else {
50+
mgr.write(set);
51+
}
4652
if (logger.isInfoEnabled()) {
4753
logger.info("Wrote " + count + " documents to MarkLogic");
4854
}
4955
}
5056
});
5157
}
5258

59+
/**
60+
* Factored out so it can be overridden for e.g. those already using MarkLogic 9, who may need to set the content
61+
* format on the manager.
62+
*
63+
* @param client
64+
* @return
65+
*/
66+
protected DocumentManager<?, ?> buildDocumentManager(DatabaseClient client) {
67+
return client.newDocumentManager();
68+
}
69+
5370
@Override
5471
public void waitForCompletion() {
5572
super.waitForCompletion();
@@ -66,4 +83,24 @@ public void waitForCompletion() {
6683
public void setReleaseDatabaseClients(boolean releaseDatabaseClients) {
6784
this.releaseDatabaseClients = releaseDatabaseClients;
6885
}
86+
87+
public void setServerTransform(ServerTransform serverTransform) {
88+
this.serverTransform = serverTransform;
89+
}
90+
91+
protected List<DatabaseClient> getDatabaseClients() {
92+
return databaseClients;
93+
}
94+
95+
protected int getClientIndex() {
96+
return clientIndex;
97+
}
98+
99+
protected boolean isReleaseDatabaseClients() {
100+
return releaseDatabaseClients;
101+
}
102+
103+
protected ServerTransform getServerTransform() {
104+
return serverTransform;
105+
}
69106
}

src/main/java/com/marklogic/client/modulesloader/impl/AbstractStaticChecker.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ protected void performBulkStaticCheck(List<LoadedAsset> assets) {
8282
protected String buildXqueryForStaticallyCheckingModule() {
8383
String xquery =
8484
"try { xdmp:invoke($uri, (), <options xmlns='xdmp:eval'><static-check>true</static-check></options>) } " +
85-
"catch ($e) { xdmp:log($e), " +
85+
"catch ($e) { " +
8686
"if ($e/*:code = 'XDMP-NOEXECUTE') then () " +
8787
"else if ($e/*:code = 'XDMP-EVALLIBMOD') then ";
8888
if (checkLibraryModules) {

src/main/java/com/marklogic/client/modulesloader/impl/DefaultModulesLoader.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public DefaultModulesLoader(XccAssetLoader xccAssetLoader) {
8080
this.xccAssetLoader = xccAssetLoader;
8181
}
8282

83-
protected void initializeDefaultTaskExecutor() {
83+
public void initializeDefaultTaskExecutor() {
8484
if (taskThreadCount > 1) {
8585
ThreadPoolTaskExecutor tpte = new ThreadPoolTaskExecutor();
8686
tpte.setCorePoolSize(taskThreadCount);
@@ -530,6 +530,9 @@ public void run() {
530530
* @param r
531531
*/
532532
protected void executeTask(Runnable r) {
533+
if (taskExecutor == null) {
534+
initializeDefaultTaskExecutor();
535+
}
533536
taskExecutor.execute(r);
534537
}
535538

0 commit comments

Comments
 (0)