/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE file at the root of the source
* tree and available online at
*
* https://github.com/keeps/roda
*/
package org.roda.core.index;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertNotNull;
import static org.testng.AssertJUnit.assertTrue;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.solr.client.solrj.SolrServerException;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.hamcrest.collection.IsCollectionWithSize;
import org.roda.core.CorporaConstants;
import org.roda.core.RodaCoreFactory;
import org.roda.core.TestsHelper;
import org.roda.core.common.RodaUtils;
import org.roda.core.common.notifications.EmailNotificationProcessor;
import org.roda.core.data.common.RodaConstants;
import org.roda.core.data.exceptions.AlreadyExistsException;
import org.roda.core.data.exceptions.AuthorizationDeniedException;
import org.roda.core.data.exceptions.GenericException;
import org.roda.core.data.exceptions.IllegalOperationException;
import org.roda.core.data.exceptions.NotFoundException;
import org.roda.core.data.exceptions.RODAException;
import org.roda.core.data.exceptions.RequestNotValidException;
import org.roda.core.data.v2.formats.Format;
import org.roda.core.data.v2.index.IndexResult;
import org.roda.core.data.v2.index.IndexRunnable;
import org.roda.core.data.v2.index.filter.EmptyKeyFilterParameter;
import org.roda.core.data.v2.index.filter.Filter;
import org.roda.core.data.v2.index.filter.SimpleFilterParameter;
import org.roda.core.data.v2.index.sort.Sorter;
import org.roda.core.data.v2.index.sublist.Sublist;
import org.roda.core.data.v2.ip.AIP;
import org.roda.core.data.v2.ip.AIPState;
import org.roda.core.data.v2.ip.IndexedAIP;
import org.roda.core.data.v2.ip.IndexedRepresentation;
import org.roda.core.data.v2.ip.Permissions;
import org.roda.core.data.v2.ip.Permissions.PermissionType;
import org.roda.core.data.v2.ip.Representation;
import org.roda.core.data.v2.ip.StoragePath;
import org.roda.core.data.v2.log.LogEntry;
import org.roda.core.data.v2.log.LogEntry.LOG_ENTRY_STATE;
import org.roda.core.data.v2.log.LogEntryParameter;
import org.roda.core.data.v2.notifications.Notification;
import org.roda.core.data.v2.notifications.Notification.NOTIFICATION_STATE;
import org.roda.core.data.v2.risks.IndexedRisk;
import org.roda.core.data.v2.risks.Risk;
import org.roda.core.data.v2.risks.Risk.SEVERITY_LEVEL;
import org.roda.core.data.v2.user.Group;
import org.roda.core.data.v2.user.RODAMember;
import org.roda.core.data.v2.user.User;
import org.roda.core.data.v2.validation.ValidationException;
import org.roda.core.index.utils.SolrUtils;
import org.roda.core.model.ModelService;
import org.roda.core.storage.DefaultStoragePath;
import org.roda.core.storage.StorageService;
import org.roda.core.storage.fs.FSUtils;
import org.roda.core.storage.fs.FileStorageService;
import org.roda.core.util.IdUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@Test(groups = {RodaConstants.TEST_GROUP_ALL, RodaConstants.TEST_GROUP_TRAVIS})
public class IndexServiceTest {
private static Path basePath;
private static Path logPath;
private static ModelService model;
private static IndexService index;
private static StorageService corporaService;
private static final Logger LOGGER = LoggerFactory.getLogger(IndexServiceTest.class);
@BeforeClass
public static void setUp() throws Exception {
basePath = TestsHelper.createBaseTempDir(IndexServiceTest.class, true);
boolean deploySolr = true;
boolean deployLdap = true;
boolean deployFolderMonitor = false;
boolean deployOrchestrator = false;
boolean deployPluginManager = false;
boolean deployDefaultResources = false;
RodaCoreFactory.instantiateTest(deploySolr, deployLdap, deployFolderMonitor, deployOrchestrator,
deployPluginManager, deployDefaultResources);
logPath = RodaCoreFactory.getLogPath();
model = RodaCoreFactory.getModelService();
index = RodaCoreFactory.getIndexService();
URL corporaURL = IndexServiceTest.class.getResource("/corpora");
corporaService = new FileStorageService(Paths.get(corporaURL.toURI()));
LOGGER.debug("Running index tests under storage {}", basePath);
}
@AfterClass
public static void tearDown() throws Exception {
RodaCoreFactory.shutdown();
FSUtils.deletePath(basePath);
}
@AfterMethod
public void cleanUp() throws RODAException {
index.execute(IndexedAIP.class, Filter.ALL, new ArrayList<>(), new IndexRunnable<IndexedAIP>() {
@Override
public void run(IndexedAIP item) throws GenericException, RequestNotValidException, AuthorizationDeniedException {
try {
model.deleteAIP(item.getId());
} catch (NotFoundException e) {
// do nothing
}
}
});
}
private void compareAIPWithIndexedAIP(final AIP aip, final IndexedAIP indexedAIP) {
assertEquals(aip.getId(), indexedAIP.getId());
assertEquals(aip.getParentId(), indexedAIP.getParentID());
for (PermissionType permissionType : PermissionType.values()) {
// users
Set<String> usersSet1 = aip.getPermissions().getUsers().get(permissionType);
Set<String> usersSet2 = indexedAIP.getPermissions().getUsers().get(permissionType);
usersSet1 = usersSet1 == null ? new HashSet<>() : usersSet1;
usersSet2 = usersSet2 == null ? new HashSet<>() : usersSet2;
assertEquals(usersSet1, usersSet2);
// groups
Set<String> groupsSet1 = aip.getPermissions().getGroups().get(permissionType);
Set<String> groupsSet2 = indexedAIP.getPermissions().getGroups().get(permissionType);
groupsSet1 = groupsSet1 == null ? new HashSet<>() : groupsSet1;
groupsSet2 = groupsSet2 == null ? new HashSet<>() : groupsSet2;
assertEquals(groupsSet1, groupsSet2);
}
assertEquals(AIPState.ACTIVE, aip.getState());
}
@Test
public void testAIPIndexCreateDelete() throws RODAException, ParseException {
// generate AIP ID
final String aipId = IdUtils.createUUID();
// Create AIP
final AIP aip = model.createAIP(aipId, corporaService,
DefaultStoragePath.parse(CorporaConstants.SOURCE_AIP_CONTAINER, CorporaConstants.SOURCE_AIP_ID),
RodaConstants.ADMIN);
index.commitAIPs();
// Retrieve, count and list AIP
final IndexedAIP indexedAip = index.retrieve(IndexedAIP.class, aipId, new ArrayList<>());
compareAIPWithIndexedAIP(aip, indexedAip);
final IndexResult<IndexedAIP> indexAips = index.find(IndexedAIP.class, null, null, new Sublist(0, 10),
Collections.emptyList());
assertEquals(1, indexAips.getTotalCount());
assertEquals(1, indexAips.getLimit());
assertEquals(0, indexAips.getOffset());
assertEquals(1, indexAips.getResults().size());
final IndexedAIP aipFromList = indexAips.getResults().get(0);
assertEquals(aip.getId(), aipFromList.getId());
assertEquals(aip.getState(), aipFromList.getState());
assertEquals(aip.getParentId(), aipFromList.getParentID());
assertEquals(indexedAip, aipFromList);
assertEquals("fonds", indexedAip.getLevel());
assertEquals("My example", indexedAip.getTitle());
assertEquals("This is a very nice example", indexedAip.getDescription());
assertEquals(RodaUtils.parseDate("0001-01-01T00:00:00.000+0000"), indexedAip.getDateInitial());
assertEquals(RodaUtils.parseDate("0002-01-01T00:00:00.000+0000"), indexedAip.getDateFinal());
// Retrieve, count and list SRO
String rep1Id = aip.getRepresentations().get(0).getId();
IndexedRepresentation rep1 = index.retrieve(IndexedRepresentation.class, IdUtils.getRepresentationId(aipId, rep1Id),
new ArrayList<>());
assertEquals(rep1Id, rep1.getId());
Filter filterParentTheAIP = new Filter();
filterParentTheAIP.add(new SimpleFilterParameter(RodaConstants.REPRESENTATION_AIP_ID, aipId));
IndexResult<IndexedRepresentation> sros = index.find(IndexedRepresentation.class, filterParentTheAIP, null,
new Sublist(0, 10), Collections.emptyList());
assertEquals(aip.getRepresentations().size(), sros.getTotalCount());
List<String> sroIDs = new ArrayList<>();
for (Representation sro : sros.getResults()) {
sroIDs.add(sro.getId());
}
List<String> representationIds = aip.getRepresentations().stream().map(r -> r.getId()).collect(Collectors.toList());
MatcherAssert.assertThat(sroIDs, Matchers.contains(representationIds.toArray()));
model.deleteAIP(aipId);
try {
index.retrieve(IndexedAIP.class, aipId, new ArrayList<>());
Assert.fail("AIP deleted but yet it was retrieved");
} catch (NotFoundException e) {
// do nothing as it was the expected exception
} catch (RODAException e) {
Assert.fail("AIP was deleted and therefore a " + NotFoundException.class.getName()
+ " should have been thrown instead of a " + e.getClass().getName());
}
}
@Test
public void testAIPIndexCreateDelete2() throws RODAException {
final String aipId = IdUtils.createUUID();
model.createAIP(aipId, corporaService,
DefaultStoragePath.parse(CorporaConstants.SOURCE_AIP_CONTAINER, CorporaConstants.SOURCE_AIP_ID_3),
RodaConstants.ADMIN);
index.commitAIPs();
Filter filter = new Filter();
filter.add(new SimpleFilterParameter(RodaConstants.INDEX_UUID, aipId));
IndexedAIP indexedAip = index.find(IndexedAIP.class, filter, null, new Sublist(0, 10), Collections.emptyList())
.getResults().get(0);
Calendar calInitial = Calendar.getInstance();
calInitial.setTime(indexedAip.getDateInitial());
assertEquals(calInitial.get(Calendar.YEAR), CorporaConstants.YEAR_1213);
Calendar calFinal = Calendar.getInstance();
calFinal.setTime(indexedAip.getDateFinal());
assertEquals(calFinal.get(Calendar.YEAR), CorporaConstants.YEAR_2003);
}
@Test
public void testAIPUpdate() throws RODAException {
// generate AIP ID
final String aipId = IdUtils.createUUID();
// testing AIP
model.createAIP(aipId, corporaService,
DefaultStoragePath.parse(CorporaConstants.SOURCE_AIP_CONTAINER, CorporaConstants.SOURCE_AIP_ID),
RodaConstants.ADMIN);
final StoragePath otherAipPath = DefaultStoragePath.parse(CorporaConstants.SOURCE_AIP_CONTAINER,
CorporaConstants.OTHER_AIP_ID);
final AIP updatedAIP = model.updateAIP(aipId, corporaService, otherAipPath, RodaConstants.ADMIN);
final IndexedAIP indexedAIP = index.retrieve(IndexedAIP.class, aipId, new ArrayList<>());
compareAIPWithIndexedAIP(updatedAIP, indexedAIP);
model.deleteAIP(aipId);
}
@Test
public void testListCollections() throws RODAException {
// set up
model.createAIP(CorporaConstants.SOURCE_AIP_ID, corporaService,
DefaultStoragePath.parse(CorporaConstants.SOURCE_AIP_CONTAINER, CorporaConstants.SOURCE_AIP_ID),
RodaConstants.ADMIN);
model.createAIP(CorporaConstants.OTHER_AIP_ID, corporaService,
DefaultStoragePath.parse(CorporaConstants.SOURCE_AIP_CONTAINER, CorporaConstants.OTHER_AIP_ID),
RodaConstants.ADMIN);
index.commitAIPs();
// TODO following filter should be in corpora constants or removed
Filter fondsFilter = new Filter(new SimpleFilterParameter("level", "fonds"));
long aipCount = index.count(IndexedAIP.class, fondsFilter);
assertEquals(1, aipCount);
final IndexResult<IndexedAIP> aips = index.find(IndexedAIP.class, fondsFilter, null, new Sublist(0, 10),
Collections.emptyList());
assertEquals(1, aips.getLimit());
assertEquals(CorporaConstants.SOURCE_AIP_ID, aips.getResults().get(0).getId());
model.deleteAIP(CorporaConstants.SOURCE_AIP_ID);
model.deleteAIP(CorporaConstants.OTHER_AIP_ID);
}
@Test
public void testSubElements() throws RODAException {
// set up
model.createAIP(CorporaConstants.SOURCE_AIP_ID, corporaService,
DefaultStoragePath.parse(CorporaConstants.SOURCE_AIP_CONTAINER, CorporaConstants.SOURCE_AIP_ID),
RodaConstants.ADMIN);
model.createAIP(CorporaConstants.OTHER_AIP_ID, corporaService,
DefaultStoragePath.parse(CorporaConstants.SOURCE_AIP_CONTAINER, CorporaConstants.OTHER_AIP_ID),
RodaConstants.ADMIN);
index.commitAIPs();
Filter filter = new Filter();
filter.add(new SimpleFilterParameter(RodaConstants.AIP_PARENT_ID, CorporaConstants.SOURCE_AIP_ID));
long aipCount = index.count(IndexedAIP.class, filter);
assertEquals(1, aipCount);
final IndexResult<IndexedAIP> aips = index.find(IndexedAIP.class, filter, null, new Sublist(0, 10),
Collections.emptyList());
assertEquals(1, aips.getLimit());
assertEquals(CorporaConstants.OTHER_AIP_ID, aips.getResults().get(0).getId());
model.deleteAIP(CorporaConstants.SOURCE_AIP_ID);
model.deleteAIP(CorporaConstants.OTHER_AIP_ID);
}
@Test
public void testGetAncestors() throws RODAException {
// set up
model.createAIP(CorporaConstants.SOURCE_AIP_ID, corporaService,
DefaultStoragePath.parse(CorporaConstants.SOURCE_AIP_CONTAINER, CorporaConstants.SOURCE_AIP_ID),
RodaConstants.ADMIN);
model.createAIP(CorporaConstants.OTHER_AIP_ID, corporaService,
DefaultStoragePath.parse(CorporaConstants.SOURCE_AIP_CONTAINER, CorporaConstants.OTHER_AIP_ID),
RodaConstants.ADMIN);
index.commitAIPs();
IndexedAIP aip = index.retrieve(IndexedAIP.class, CorporaConstants.OTHER_AIP_ID, new ArrayList<>());
List<IndexedAIP> ancestors = index.retrieveAncestors(aip, new ArrayList<>());
MatcherAssert.assertThat(ancestors,
Matchers.hasItem(Matchers.<IndexedAIP> hasProperty("id", Matchers.equalTo(CorporaConstants.SOURCE_AIP_ID))));
}
@Test
public void testGetElementWithoutParentId() throws RODAException {
// generate AIP ID
final String aipId = IdUtils.createUUID();
// Create AIP
model.createAIP(aipId, corporaService,
DefaultStoragePath.parse(CorporaConstants.SOURCE_AIP_CONTAINER, CorporaConstants.SOURCE_AIP_ID),
RodaConstants.ADMIN);
index.commitAIPs();
Filter filter = new Filter();
filter.add(new SimpleFilterParameter(RodaConstants.AIP_LEVEL, "fonds"));
filter.add(new EmptyKeyFilterParameter(RodaConstants.AIP_PARENT_ID));
IndexResult<IndexedAIP> findDescriptiveMetadata = index.find(IndexedAIP.class, filter, null, new Sublist(),
Collections.emptyList());
assertNotNull(findDescriptiveMetadata);
MatcherAssert.assertThat(findDescriptiveMetadata.getResults(), IsCollectionWithSize.hasSize(1));
// cleanup
model.deleteAIP(aipId);
}
@Test
public void testGetLogEntriesCount() throws GenericException, RequestNotValidException, AuthorizationDeniedException,
NotFoundException, InterruptedException {
// cleaning up action log entries on index (if any)
index.deleteAllActionLog();
LogEntry entry = new LogEntry();
entry.setActionComponent("Action");
entry.setActionMethod("Method");
entry.setAddress("Address");
entry.setDatetime(new Date());
entry.setDuration(10L);
entry.setId("ID");
entry.setRelatedObjectID("Related");
entry.setUsername("Username");
entry.setState(LOG_ENTRY_STATE.SUCCESS);
List<LogEntryParameter> parameters = new ArrayList<>();
parameters.add(new LogEntryParameter("NAME1", "VALUE1"));
parameters.add(new LogEntryParameter("NAME2", "VALUE2"));
entry.setParameters(parameters);
model.addLogEntry(entry, logPath);
index.commit(LogEntry.class);
Filter filterDescription = new Filter();
filterDescription.add(new SimpleFilterParameter(RodaConstants.LOG_ID, "ID"));
MatcherAssert.assertThat(index.count(LogEntry.class, filterDescription), Matchers.is(1L));
Filter filterDescription2 = new Filter();
filterDescription2.add(new SimpleFilterParameter(RodaConstants.LOG_ID, "ID2"));
MatcherAssert.assertThat(index.count(LogEntry.class, filterDescription2), Matchers.is(0L));
}
@Test
public void testFindLogEntry() throws GenericException, RequestNotValidException, AuthorizationDeniedException,
NotFoundException, InterruptedException {
LogEntry entry = new LogEntry();
entry.setActionComponent(RodaConstants.LOG_ACTION_COMPONENT);
entry.setActionMethod("Method");
entry.setAddress("address");
entry.setDatetime(new Date());
entry.setDuration(10L);
entry.setId("id");
entry.setRelatedObjectID("related");
entry.setUsername("username");
entry.setState(LOG_ENTRY_STATE.SUCCESS);
List<LogEntryParameter> parameters = new ArrayList<>();
parameters.add(new LogEntryParameter("NAME1", "VALUE1"));
parameters.add(new LogEntryParameter("NAME2", "VALUE2"));
entry.setParameters(parameters);
model.addLogEntry(entry, logPath);
index.commit(LogEntry.class);
Filter filterDescription = new Filter();
filterDescription.add(new SimpleFilterParameter(RodaConstants.LOG_ID, "id"));
IndexResult<LogEntry> entries = index.find(LogEntry.class, filterDescription, null, new Sublist(),
Collections.emptyList());
assertEquals(entries.getTotalCount(), 1);
assertEquals(entries.getResults().get(0).getActionComponent(), RodaConstants.LOG_ACTION_COMPONENT);
Filter filterDescription2 = new Filter();
filterDescription2.add(new SimpleFilterParameter(RodaConstants.LOG_ID, "id2"));
IndexResult<LogEntry> entries2 = index.find(LogEntry.class, filterDescription2, null, new Sublist(),
Collections.emptyList());
assertEquals(entries2.getTotalCount(), 0);
}
@Test
public void testReindexLogEntry() throws GenericException, RequestNotValidException, AuthorizationDeniedException,
NotFoundException, InterruptedException {
Long number = 10L;
for (int i = 0; i < number; i++) {
LogEntry entry = new LogEntry();
entry.setId("ID" + i);
entry.setActionComponent("ACTION:" + i);
entry.setActionMethod("Method:" + i);
entry.setAddress("ADDRESS");
entry.setDatetime(new Date());
entry.setDuration(i);
entry.setRelatedObjectID("RELATED:" + i);
entry.setUsername("USER:" + i);
entry.setState(LOG_ENTRY_STATE.SUCCESS);
List<LogEntryParameter> parameters = new ArrayList<>();
parameters.add(new LogEntryParameter("NAME1", "VALUE1"));
parameters.add(new LogEntryParameter("NAME2", "VALUE2"));
entry.setParameters(parameters);
model.addLogEntry(entry, logPath, false);
}
index.commit(LogEntry.class);
model.findOldLogsAndMoveThemToStorage(logPath, null);
index.reindexActionLogs();
index.commit(LogEntry.class);
Filter f1 = new Filter();
f1.add(new SimpleFilterParameter(RodaConstants.LOG_ACTION_COMPONENT, "ACTION:0"));
IndexResult<LogEntry> entries1 = index.find(LogEntry.class, f1, null, new Sublist(0, 10), Collections.emptyList());
MatcherAssert.assertThat(entries1.getTotalCount(), Matchers.is(1L));
Filter f2 = new Filter();
f2.add(new SimpleFilterParameter(RodaConstants.LOG_ADDRESS, "ADDRESS"));
IndexResult<LogEntry> entries2 = index.find(LogEntry.class, f2, null, new Sublist(0, 10), Collections.emptyList());
MatcherAssert.assertThat(entries2.getTotalCount(), Matchers.is(number));
}
@Test
public void testReindexAIP() throws ParseException, RequestNotValidException, GenericException,
AuthorizationDeniedException, AlreadyExistsException, NotFoundException, ValidationException {
index.clearIndex(RodaConstants.INDEX_AIP);
for (int i = 0; i < 10; i++) {
final String aipId = IdUtils.createUUID();
model.createAIP(aipId, corporaService,
DefaultStoragePath.parse(CorporaConstants.SOURCE_AIP_CONTAINER, CorporaConstants.SOURCE_AIP_ID), false,
RodaConstants.ADMIN);
}
index.reindexAIPs();
long count = index.count(IndexedAIP.class, new Filter());
assertEquals(10L, count);
}
@Test
public void indexMembers() throws AlreadyExistsException, GenericException, RequestNotValidException,
IllegalOperationException, NotFoundException {
Set<String> groups = new HashSet<>();
groups.add("administrators");
Set<String> users = new HashSet<>();
users.add("admin");
Set<String> roles = new HashSet<>();
roles.add(RodaConstants.REPOSITORY_PERMISSIONS_DESCRIPTIVE_METADATA_UPDATE);
for (int i = 0; i < 5; i++) {
if (i % 2 == 0) {
User user = new User();
user.setActive(true);
user.setAllRoles(roles);
user.setDirectRoles(roles);
user.setGuest(false);
user.setId("USER" + i);
user.setName("NAMEUSER" + i);
user.setFullName("NAMEUSER" + i);
user.setEmail("mail_" + i + "@example.com");
user.setGroups(groups);
model.createUser(user, true);
} else {
Group group = new Group();
group.setActive(true);
group.setAllRoles(roles);
group.setDirectRoles(roles);
group.setId("GROUP" + i);
group.setName("NAMEGROUP" + i);
group.setFullName("NAMEGROUP" + i);
group.setUsers(users);
model.createGroup(group, true);
}
}
index.commit(RODAMember.class);
Filter filterUSER1 = new Filter();
filterUSER1.add(new SimpleFilterParameter(RodaConstants.MEMBERS_NAME, "NAMEUSER0"));
filterUSER1.add(new SimpleFilterParameter(RodaConstants.MEMBERS_IS_USER, "true"));
MatcherAssert.assertThat(index.count(RODAMember.class, filterUSER1), Matchers.is(1L));
Filter filterGroup = new Filter();
filterGroup.add(new SimpleFilterParameter(RodaConstants.MEMBERS_NAME, "NAMEGROUP1"));
filterGroup.add(new SimpleFilterParameter(RodaConstants.MEMBERS_IS_USER, "false"));
MatcherAssert.assertThat(index.count(RODAMember.class, filterGroup), Matchers.is(1L));
}
@Test
public void testIdWithComma() throws RODAException {
// generate AIP ID
final String origAipId = "id, with, comma";
final String aipId = IdUtils.createUUID(origAipId);
// Create AIP
model.createAIP(aipId, corporaService,
DefaultStoragePath.parse(CorporaConstants.SOURCE_AIP_CONTAINER, CorporaConstants.SOURCE_AIP_ID),
RodaConstants.ADMIN);
index.commitAIPs();
IndexResult<IndexedAIP> find = index.find(IndexedAIP.class, null, null, new Sublist(0, 10),
Collections.emptyList());
assertEquals(1, find.getTotalCount());
IndexedAIP aip = index.retrieve(IndexedAIP.class, aipId, new ArrayList<>());
assertNotNull(aip);
// cleanup
model.deleteAIP(aipId);
}
@Test
public void testRiskIndex() {
try {
Risk risk = new Risk();
risk.setName("Risk name");
risk.setDescription("Risk description");
risk.setIdentifiedOn(new Date());
risk.setIdentifiedBy("Risk identifier");
risk.setCategory("Risk category");
risk.setNotes("Risk notes");
risk.setPreMitigationProbability(4);
risk.setPreMitigationImpact(4);
risk.setPreMitigationSeverity(16);
risk.setPreMitigationSeverityLevel(SEVERITY_LEVEL.HIGH);
risk.setPreMitigationNotes("Pre Notes");
risk.setPostMitigationProbability(3);
risk.setPostMitigationImpact(2);
risk.setPostMitigationSeverity(6);
risk.setPostMitigationSeverityLevel(SEVERITY_LEVEL.MODERATE);
risk.setPostMitigationNotes("Pos Notes");
risk.setMitigationStrategy("Mitigation Strategy");
risk.setMitigationOwnerType("Owner type");
risk.setMitigationOwner("Owner");
risk.setMitigationRelatedEventIdentifierType("Mitigation REI type");
risk.setMitigationRelatedEventIdentifierValue("Mitigation REI value");
risk.setCreatedOn(new Date());
risk.setCreatedBy("admin");
risk.setUpdatedOn(new Date());
risk.setUpdatedBy("admin");
model.createRisk(risk, false);
index.commit(IndexedRisk.class);
Risk risk2 = model.retrieveRisk(risk.getId());
assertNotNull(risk2);
assertEquals(risk.getId(), risk2.getId());
assertEquals(risk.getName(), risk2.getName());
IndexResult<IndexedRisk> find = index.find(IndexedRisk.class, null, null, new Sublist(0, 10),
Collections.emptyList());
assertEquals(1, find.getTotalCount());
Risk risk3 = index.retrieve(IndexedRisk.class, risk.getId(), new ArrayList<>());
assertNotNull(risk3);
assertEquals(risk.getId(), risk3.getId());
assertEquals(risk.getName(), risk3.getName());
risk3.setName("Risk New Name");
Map<String, String> properties = new HashMap<>();
properties.put(RodaConstants.VERSION_ACTION, RodaConstants.VersionAction.UPDATED.toString());
model.updateRisk(risk3, properties, false, 0);
Risk risk4 = index.retrieve(IndexedRisk.class, risk.getId(), new ArrayList<>());
assertNotNull(risk4);
assertEquals(risk.getId(), risk4.getId());
assertEquals(risk4.getName(), "Risk New Name");
model.deleteRisk(risk.getId(), false);
} catch (GenericException | RequestNotValidException | NotFoundException | AuthorizationDeniedException e) {
e.printStackTrace(System.err);
assertTrue(false);
}
}
@Test
public void testFormatIndex() throws RODAException {
Format format = new Format();
format.setName("Portable Document Format");
format.setDefinition("PDF definition");
format.setCategories(Arrays.asList("Page Layout Files"));
format.setLatestVersion("1.7");
format.setPopularity(4);
format.setDeveloper("Adobe Systems");
format.setInitialRelease(new Date());
format.setStandard("ISO 32000-1");
format.setOpenFormat(true);
format.setWebsites(Arrays.asList("https://www.adobe.com/devnet/pdf/pdf_reference_archive.html"));
format.setProvenanceInformation("https://en.wikipedia.org/wiki/Portable_Document_Format");
List<String> extensions = new ArrayList<>();
extensions.add(".pdf");
format.setExtensions(extensions);
List<String> mimetypes = new ArrayList<>();
mimetypes.add("application/pdf");
format.setMimetypes(mimetypes);
List<String> pronoms = new ArrayList<>();
pronoms.add("fmt/100");
format.setPronoms(pronoms);
List<String> utis = new ArrayList<>();
utis.add("com.adobe.pdf");
format.setUtis(utis);
model.createFormat(format, false);
index.commit(Format.class);
Format format2 = model.retrieveFormat(format.getId());
assertNotNull(format2);
assertEquals(format.getId(), format2.getId());
assertEquals(format.getName(), format2.getName());
IndexResult<Format> find = index.find(Format.class, null, null, new Sublist(0, 10), Collections.emptyList());
assertEquals(1, find.getTotalCount());
Format format3 = index.retrieve(Format.class, format.getId(), new ArrayList<>());
assertNotNull(format3);
assertEquals(format.getId(), format3.getId());
assertEquals(format.getName(), format3.getName());
format3.setName("Format New Name");
model.updateFormat(format3, false);
Format format4 = index.retrieve(Format.class, format.getId(), new ArrayList<>());
assertNotNull(format4);
assertEquals(format.getId(), format4.getId());
assertEquals(format4.getName(), "Format New Name");
model.deleteFormat(format.getId(), false);
}
@Test
public void testMessageIndex() throws ConfigurationException, RODAException {
Notification notification = new Notification();
notification.setSubject("Message subject");
notification.setBody("Message body");
notification.setSentOn(new Date());
notification.setFromUser("Test Message Index");
notification.setRecipientUsers(Arrays.asList("recipientuser@example.com"));
Notification n = model.createNotification(notification, new EmailNotificationProcessor("test-email-template.vm"));
// notification state must be FAILED because SMTP is not configured on test
// environment
Assert.assertEquals(n.getState(), NOTIFICATION_STATE.FAILED);
index.commit(Notification.class);
Notification message2 = model.retrieveNotification(notification.getId());
assertNotNull(message2);
assertEquals(notification.getId(), message2.getId());
assertEquals(notification.getSubject(), message2.getSubject());
IndexResult<Notification> find = index.find(Notification.class, null, null, new Sublist(0, 10),
Collections.emptyList());
assertEquals(1, find.getTotalCount());
Notification message3 = index.retrieve(Notification.class, notification.getId(), new ArrayList<>());
assertNotNull(message3);
assertEquals(notification.getId(), message3.getId());
assertEquals(message3.getSubject(), message3.getSubject());
message3.setSubject("Message New Subject");
model.updateNotification(message3);
Notification message4 = index.retrieve(Notification.class, notification.getId(), new ArrayList<>());
assertNotNull(message4);
assertEquals(notification.getId(), message4.getId());
assertEquals(message4.getSubject(), "Message New Subject");
model.deleteNotification(notification.getId());
}
@Test
public void testIteration() throws RODAException, SolrServerException, IOException {
// populate index
for (int i = 0; i < 10000; i++) {
String id = "id_" + i;
AIP aip = new AIP();
aip.setId(id);
aip.setState(AIPState.ACTIVE);
aip.setDescriptiveMetadata(new ArrayList<>());
aip.setRepresentations(new ArrayList<>());
aip.setPermissions(new Permissions());
index.getSolrClient().add(SolrUtils.getIndexName(AIP.class).get(0),
SolrUtils.aipToSolrInputDocument(aip, new ArrayList<>(), model, true));
index.commit(IndexedAIP.class);
}
List<String> results = new ArrayList<>();
IndexResult<IndexedAIP> find;
int offset = 0;
int blockSize = 100;
do {
find = RodaCoreFactory.getIndexService().find(IndexedAIP.class, Filter.ALL, Sorter.NONE,
new Sublist(offset, blockSize), Collections.emptyList());
offset += find.getLimit();
// Add all ids to result list
results.addAll(find.getResults().stream().map(aip -> aip.getId()).collect(Collectors.toList()));
} while (find.getTotalCount() > find.getOffset() + find.getLimit());
// check if they are all there
for (int i = 0; i < 10000; i++) {
String id = "id_" + i;
Assert.assertTrue(results.contains(id), "Could not find expected id: " + id);
}
// check if none is repeated
Set<String> set = new HashSet<>();
set.addAll(results);
Assert.assertEquals(results.size(), set.size());
}
}