Skip to content

Commit 4f5de6f

Browse files
committed
Adding test for nested documents indexing and search
1 parent 747f0ff commit 4f5de6f

1 file changed

Lines changed: 159 additions & 0 deletions

File tree

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
/**
2+
* The contents of this file are subject to the license and copyright
3+
* detailed in the LICENSE file at the root of the source
4+
* tree and available online at
5+
*
6+
* https://github.com/keeps/roda
7+
*/
8+
package org.roda.core.index;
9+
10+
import static org.testng.AssertJUnit.assertEquals;
11+
import static org.testng.AssertJUnit.assertTrue;
12+
13+
import java.io.IOException;
14+
import java.net.URL;
15+
import java.nio.file.Path;
16+
import java.nio.file.Paths;
17+
import java.util.Arrays;
18+
import java.util.Collections;
19+
20+
import org.apache.solr.client.solrj.SolrQuery;
21+
import org.apache.solr.client.solrj.response.QueryResponse;
22+
import org.roda.core.CorporaConstants;
23+
import org.roda.core.RodaCoreFactory;
24+
import org.roda.core.TestsHelper;
25+
import org.roda.core.config.TestConfig;
26+
import org.roda.core.data.common.RodaConstants;
27+
import org.roda.core.data.exceptions.RODAException;
28+
import org.roda.core.data.v2.index.IndexResult;
29+
import org.roda.core.data.v2.index.filter.AndFiltersParameters;
30+
import org.roda.core.data.v2.index.filter.Filter;
31+
import org.roda.core.data.v2.index.filter.ParentWhichFilterParameter;
32+
import org.roda.core.data.v2.index.filter.SimpleFilterParameter;
33+
import org.roda.core.data.v2.index.sort.Sorter;
34+
import org.roda.core.data.v2.index.sublist.Sublist;
35+
import org.roda.core.data.v2.ip.AIP;
36+
import org.roda.core.data.v2.ip.IndexedAIP;
37+
import org.roda.core.index.utils.IterableIndexResult;
38+
import org.roda.core.model.ModelService;
39+
import org.roda.core.security.LdapUtilityTestHelper;
40+
import org.roda.core.storage.DefaultStoragePath;
41+
import org.roda.core.storage.StorageService;
42+
import org.roda.core.storage.fs.FSUtils;
43+
import org.roda.core.storage.fs.FileStorageService;
44+
import org.roda.core.util.IdUtils;
45+
import org.slf4j.Logger;
46+
import org.slf4j.LoggerFactory;
47+
import org.springframework.boot.test.context.SpringBootTest;
48+
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
49+
import org.testng.annotations.AfterClass;
50+
import org.testng.annotations.AfterMethod;
51+
import org.testng.annotations.BeforeClass;
52+
import org.testng.annotations.Test;
53+
54+
@SpringBootTest(classes = TestConfig.class)
55+
@Test(groups = {RodaConstants.TEST_GROUP_ALL, RodaConstants.TEST_GROUP_DEV, RodaConstants.TEST_GROUP_TRAVIS})
56+
public class NestedDocumentSearchTest extends AbstractTestNGSpringContextTests {
57+
58+
private static final Logger LOGGER = LoggerFactory.getLogger(NestedDocumentSearchTest.class);
59+
60+
private static Path basePath;
61+
private static ModelService model;
62+
private static IndexService index;
63+
private static LdapUtilityTestHelper ldapUtilityTestHelper;
64+
private static StorageService corporaService;
65+
66+
@BeforeClass
67+
public void setUp() throws Exception {
68+
basePath = TestsHelper.createBaseTempDir(getClass(), true);
69+
ldapUtilityTestHelper = new LdapUtilityTestHelper();
70+
71+
RodaCoreFactory.instantiateTest(true, true, false, false, false, false, false,
72+
ldapUtilityTestHelper.getLdapUtility());
73+
74+
model = RodaCoreFactory.getModelService();
75+
index = RodaCoreFactory.getIndexService();
76+
77+
URL corporaURL = getClass().getResource("/corpora");
78+
corporaService = new FileStorageService(Paths.get(corporaURL.toURI()));
79+
80+
LOGGER.debug("Running nested document search tests under {}", basePath);
81+
}
82+
83+
@AfterClass
84+
public void tearDown() throws Exception {
85+
IndexTestUtils.resetIndex();
86+
ldapUtilityTestHelper.shutdown();
87+
RodaCoreFactory.shutdown();
88+
FSUtils.deletePath(basePath);
89+
}
90+
91+
@AfterMethod
92+
public void cleanUp() throws RODAException {
93+
try (IterableIndexResult<IndexedAIP> result = index.findAll(IndexedAIP.class, Filter.ALL, Collections.emptyList())) {
94+
for (IndexedAIP aip : result) {
95+
try {
96+
model.deleteAIP(aip.getId());
97+
} catch (Exception e) {
98+
// ignore
99+
}
100+
}
101+
index.clearAIPs();
102+
} catch (IOException e) {
103+
LOGGER.error("Error cleaning up AIPs", e);
104+
} finally {
105+
index.commitAIPs();
106+
}
107+
}
108+
109+
@Test
110+
public void testParentWhichFilterFindsEmailArchiveAIPByChildSender() throws Exception {
111+
// Create AIP and attach emailarchive descriptive metadata
112+
String aipId = IdUtils.createUUID();
113+
model.createAIP(aipId, corporaService,
114+
DefaultStoragePath.parse(CorporaConstants.SOURCE_AIP_CONTAINER, CorporaConstants.SOURCE_AIP_EMPTY),
115+
RodaConstants.ADMIN);
116+
117+
org.roda.core.storage.Binary metaBinary = corporaService
118+
.getBinary(DefaultStoragePath.parse(CorporaConstants.SOURCE_DESC_METADATA_CONTAINER,
119+
CorporaConstants.EMAIL_ARCHIVE_FULL_FILE));
120+
121+
model.createDescriptiveMetadata(aipId, "emailarchive.xml", metaBinary.getContent(),
122+
CorporaConstants.EMAIL_ARCHIVE_METADATA_TYPE, null, RodaConstants.ADMIN);
123+
124+
// Reindex and commit
125+
AIP aip = model.retrieveAIP(aipId);
126+
index.reindexAIP(aip);
127+
index.commitAIPs();
128+
129+
// Layer 1: parent AIP is indexed
130+
long parentCount = index.count(IndexedAIP.class,
131+
new Filter(new SimpleFilterParameter(RodaConstants.INDEX_UUID, aipId)));
132+
assertEquals("Parent AIP should be indexed", 1L, parentCount);
133+
134+
// Layer 2: content_type field is populated on the parent document
135+
long contentTypeCount = index.count(IndexedAIP.class,
136+
new Filter(new SimpleFilterParameter("content_type", "emailarchive")));
137+
assertEquals("AIP should be findable by content_type=emailarchive", 1L, contentTypeCount);
138+
139+
// Layer 3: child email documents are indexed in Solr
140+
QueryResponse childResp = index.getSolrClient().query(RodaConstants.INDEX_AIP,
141+
new SolrQuery("content_type:email").setRows(0));
142+
long childCount = childResp.getResults().getNumFound();
143+
assertTrue("Child email documents should be indexed in Solr (found " + childCount + ")", childCount > 0);
144+
145+
// Layer 4: block-join ParentWhichFilterParameter returns the parent AIP
146+
Filter nestedFilter = new Filter(
147+
new ParentWhichFilterParameter(
148+
new SimpleFilterParameter("content_type", "emailarchive"),
149+
new AndFiltersParameters(Arrays.asList(
150+
new SimpleFilterParameter("sender_s", "joao.silva@empresa.pt"),
151+
new SimpleFilterParameter("content_type", "email")))));
152+
153+
IndexResult<IndexedAIP> result = index.find(IndexedAIP.class, nestedFilter, Sorter.NONE,
154+
new Sublist(0, 10), Collections.emptyList());
155+
156+
assertEquals("ParentWhichFilterParameter should return exactly 1 AIP", 1L, result.getTotalCount());
157+
assertEquals("Returned AIP id should match", aipId, result.getResults().get(0).getId());
158+
}
159+
}

0 commit comments

Comments
 (0)