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

Commit 6484db1

Browse files
authored
Merge pull request #190 from marklogic/feature/cascade
Can now configure whether processors cascade
2 parents ab8f695 + 2e77d4f commit 6484db1

File tree

5 files changed

+113
-30
lines changed

5 files changed

+113
-30
lines changed

src/main/java/com/marklogic/client/ext/file/CascadingPropertiesDrivenDocumentFileProcessor.java

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,16 @@
2727
/**
2828
* Adds a stack to store Properties objects while traversing a directory tree. Implements {@code FileVisitor} so that
2929
* it can be informed when {@code DefaultDocumentFileReader} is entering and exiting a directory.
30+
*
31+
* To preserve backwards compatibility in subclasses, cascading is disabled by default. This will likely change in 5.0
32+
* to be enabled by default.
33+
*
34+
* @since 4.6.0
3035
*/
3136
abstract class CascadingPropertiesDrivenDocumentFileProcessor extends PropertiesDrivenDocumentFileProcessor implements FileVisitor<Path> {
3237

3338
final private Stack<Properties> propertiesStack = new Stack<>();
39+
private boolean cascadingEnabled = false;
3440

3541
protected CascadingPropertiesDrivenDocumentFileProcessor(String propertiesFilename) {
3642
super(propertiesFilename);
@@ -42,21 +48,25 @@ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) th
4248
if (collectionsPropertiesFile.exists()) {
4349
this.loadProperties(collectionsPropertiesFile);
4450
} else {
45-
if (!propertiesStack.isEmpty()) {
51+
if (cascadingEnabled && !propertiesStack.isEmpty()) {
4652
this.setProperties(propertiesStack.peek());
4753
} else {
4854
this.setProperties(new Properties());
4955
}
5056
}
51-
propertiesStack.push(this.getProperties());
57+
if (cascadingEnabled) {
58+
propertiesStack.push(this.getProperties());
59+
}
5260
return FileVisitResult.CONTINUE;
5361
}
5462

5563
@Override
5664
public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
57-
propertiesStack.pop();
58-
if (!propertiesStack.isEmpty()) {
59-
this.setProperties(propertiesStack.peek());
65+
if (cascadingEnabled) {
66+
propertiesStack.pop();
67+
if (!propertiesStack.isEmpty()) {
68+
this.setProperties(propertiesStack.peek());
69+
}
6070
}
6171
return FileVisitResult.CONTINUE;
6272
}
@@ -70,4 +80,12 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
7080
public FileVisitResult visitFileFailed(Path file, IOException exc) {
7181
return FileVisitResult.CONTINUE;
7282
}
83+
84+
public boolean isCascadingEnabled() {
85+
return cascadingEnabled;
86+
}
87+
88+
public void setCascadingEnabled(boolean cascadingEnabled) {
89+
this.cascadingEnabled = cascadingEnabled;
90+
}
7391
}

src/main/java/com/marklogic/client/ext/file/GenericFileLoader.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ public class GenericFileLoader extends LoggingObject implements FileLoader {
5353
private String[] collections;
5454
private TokenReplacer tokenReplacer;
5555
private String[] additionalBinaryExtensions;
56+
private boolean cascadeCollections;
57+
private boolean cascadePermissions;
5658

5759
/**
5860
* The given DatabaseClient is used to construct a BatchWriter that writes to MarkLogic via the REST API. The
@@ -186,6 +188,15 @@ public void prepareAbstractDocumentFileReader(AbstractDocumentFileReader reader)
186188
if (additionalBinaryExtensions != null && processor instanceof SupportsAdditionalBinaryExtensions) {
187189
((SupportsAdditionalBinaryExtensions) processor).setAdditionalBinaryExtensions(additionalBinaryExtensions);
188190
}
191+
192+
// Awful hack for 4.6.0. In 5.0, the hope is to replace the processor-specific fields on this class with
193+
// a "Config"-type class that can be passed to each processor.
194+
if (processor instanceof PermissionsFileDocumentFileProcessor) {
195+
((PermissionsFileDocumentFileProcessor)processor).setCascadingEnabled(this.cascadePermissions);
196+
}
197+
if (processor instanceof CollectionsFileDocumentFileProcessor) {
198+
((CollectionsFileDocumentFileProcessor)processor).setCascadingEnabled(this.cascadeCollections);
199+
}
189200
});
190201
}
191202

@@ -301,4 +312,36 @@ public void setBatchSize(Integer batchSize) {
301312
public void setBatchWriter(BatchWriter batchWriter) {
302313
this.batchWriter = batchWriter;
303314
}
315+
316+
/**
317+
* @param cascadeCollections
318+
* @since 4.6.0
319+
*/
320+
public void setCascadeCollections(boolean cascadeCollections) {
321+
this.cascadeCollections = cascadeCollections;
322+
}
323+
324+
/**
325+
* @param cascadePermissions
326+
* @since 4.6.0
327+
*/
328+
public void setCascadePermissions(boolean cascadePermissions) {
329+
this.cascadePermissions = cascadePermissions;
330+
}
331+
332+
/**
333+
* @return
334+
* @since 4.6.0
335+
*/
336+
public boolean isCascadeCollections() {
337+
return cascadeCollections;
338+
}
339+
340+
/**
341+
* @return
342+
* @since 4.6.0
343+
*/
344+
public boolean isCascadePermissions() {
345+
return cascadePermissions;
346+
}
304347
}

src/test/java/com/marklogic/client/ext/AbstractIntegrationTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ protected final void verifyCollections(String uri, String... collections) {
8282

8383
protected final void verifyPermissions(String uri, String... permissionsRolesAndCapabilities) {
8484
verifyMetadata(uri, metadata -> {
85+
// TODO This will likely need to be modified once we shift the tests to not use an admin user, and thus
86+
// the user will have to specify at least one update permission.
87+
if (permissionsRolesAndCapabilities.length == 0) {
88+
assertEquals(0, metadata.getPermissions().size());
89+
}
8590
for (int i = 0; i < permissionsRolesAndCapabilities.length; i += 2) {
8691
String role = permissionsRolesAndCapabilities[i];
8792
assertTrue(metadata.getPermissions().containsKey(role), "Did not find permissions with role: " +

src/test/java/com/marklogic/client/ext/file/CascadeCollectionsAndPermissionsTest.java

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,31 @@ public class CascadeCollectionsAndPermissionsTest extends AbstractIntegrationTes
2525
final private String PARENT_COLLECTION = "ParentCollection";
2626
final private String CHILD_COLLECTION = "ChildCollection";
2727

28+
29+
private GenericFileLoader loader;
30+
2831
@BeforeEach
29-
public void setup() {
32+
void setup() {
3033
client = newClient(MODULES_DATABASE);
3134
DatabaseClient modulesClient = client;
3235
modulesClient.newServerEval().xquery("cts:uris((), (), cts:true-query()) ! xdmp:document-delete(.)").eval();
36+
loader = new GenericFileLoader(client);
37+
loader.setCascadeCollections(true);
38+
loader.setCascadePermissions(true);
3339
}
3440

3541
@Test
36-
public void parentWithBothProperties() {
37-
String directory = "src/test/resources/process-files/cascading-metadata-test/parent1-withCP";
38-
GenericFileLoader loader = new GenericFileLoader(client);
39-
loader.loadFiles(directory);
42+
void parentWithBothProperties() {
43+
loader.loadFiles("src/test/resources/process-files/cascading-metadata-test/parent1-withCP");
4044

41-
verifyCollections( "/child1_1-noCP/test.json", PARENT_COLLECTION);
42-
verifyPermissions( "/child1_1-noCP/test.json", "rest-writer", "update");
45+
verifyCollections("/child1_1-noCP/test.json", PARENT_COLLECTION);
46+
verifyPermissions("/child1_1-noCP/test.json", "rest-writer", "update");
4347

44-
verifyCollections( "/child1_2-withCP/test.json", CHILD_COLLECTION);
45-
verifyPermissions( "/child1_2-withCP/test.json", "rest-reader", "read");
48+
verifyCollections("/child1_2-withCP/test.json", CHILD_COLLECTION);
49+
verifyPermissions("/child1_2-withCP/test.json", "rest-reader", "read");
4650

47-
verifyCollections( "/child3_1-withCP/grandchild3_1_1-noCP/test.json", CHILD_COLLECTION);
48-
verifyPermissions( "/child3_1-withCP/grandchild3_1_1-noCP/test.json", "rest-reader", "read");
51+
verifyCollections("/child3_1-withCP/grandchild3_1_1-noCP/test.json", CHILD_COLLECTION);
52+
verifyPermissions("/child3_1-withCP/grandchild3_1_1-noCP/test.json", "rest-reader", "read");
4953

5054
verifyCollections("/child1/child1.json", "ParentCollection");
5155
verifyPermissions("/child1/child1.json", "rest-writer", "update");
@@ -58,21 +62,32 @@ public void parentWithBothProperties() {
5862
}
5963

6064
@Test
61-
public void parentWithNoProperties() {
62-
String directory = "src/test/resources/process-files/cascading-metadata-test/parent2-noCP";
63-
GenericFileLoader loader = new GenericFileLoader(client);
64-
loader.loadFiles(directory);
65+
void parentWithNoProperties() {
66+
loader.loadFiles("src/test/resources/process-files/cascading-metadata-test/parent2-noCP");
67+
68+
verifyCollections("/child2_1-withCP/test.json", CHILD_COLLECTION);
69+
verifyPermissions("/child2_1-withCP/test.json", "rest-reader", "read");
6570

66-
verifyCollections( "/child2_1-withCP/test.json", CHILD_COLLECTION);
67-
verifyPermissions( "/child2_1-withCP/test.json", "rest-reader", "read");
71+
verifyCollections("/child2_2-noCP/test.json");
72+
verifyPermissions("/child2_2-noCP/test.json");
6873

69-
verifyCollections( "/child2_2-noCP/test.json");
70-
verifyPermissions( "/child2_2-noCP/test.json");
74+
verifyCollections("/child2_3-withCnoP/test.json", PARENT_COLLECTION);
75+
verifyPermissions("/child2_3-withCnoP/test.json");
7176

72-
verifyCollections( "/child2_3-withCnoP/test.json", PARENT_COLLECTION);
73-
verifyPermissions( "/child2_3-withCnoP/test.json");
77+
verifyCollections("/child2_3-withCnoP/grandchild2_3_1-withPnoC/test.json", PARENT_COLLECTION);
78+
verifyPermissions("/child2_3-withCnoP/grandchild2_3_1-withPnoC/test.json", "rest-reader", "read");
79+
}
80+
81+
/**
82+
* Verifies that by default, cascading is disabled. This is to preserve backwards compatibility in 4.x. We
83+
* expect to change this for 5.0.
84+
*/
85+
@Test
86+
void cascadingDisabled() {
87+
loader = new GenericFileLoader(client);
7488

75-
verifyCollections( "/child2_3-withCnoP/grandchild2_3_1-withPnoC/test.json", PARENT_COLLECTION);
76-
verifyPermissions( "/child2_3-withCnoP/grandchild2_3_1-withPnoC/test.json", "rest-reader", "read");
89+
loader.loadFiles("src/test/resources/process-files/cascading-metadata-test/parent1-withCP");
90+
verifyCollections("/child1_1-noCP/test.json");
91+
verifyPermissions("/child1_1-noCP/test.json");
7792
}
7893
}

src/test/java/com/marklogic/client/ext/modulesloader/impl/LoadModulesTest.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@
3636
import java.util.Set;
3737
import java.util.regex.Pattern;
3838

39-
import static org.junit.jupiter.api.Assertions.*;
39+
import static org.junit.jupiter.api.Assertions.assertEquals;
40+
import static org.junit.jupiter.api.Assertions.assertTrue;
41+
import static org.junit.jupiter.api.Assertions.fail;
4042

4143
public class LoadModulesTest extends AbstractIntegrationTest {
4244

@@ -48,7 +50,7 @@ public void setup() {
4850
client = newClient(MODULES_DATABASE);
4951
client.newServerEval().xquery("cts:uris((), (), cts:true-query()) ! xdmp:document-delete(.)").eval();
5052
modulesClient = client;
51-
assertEquals(0, getUriCountInModulesDatabase(), "No new modules should have been created");
53+
assertEquals(0, getUriCountInModulesDatabase(), "No modules should exist");
5254

5355
/**
5456
* Odd - the Client REST API doesn't allow for loading namespaces when the DatabaseClient has a database

0 commit comments

Comments
 (0)