/**
* Licensed to The Apereo Foundation under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
*
* The Apereo Foundation licenses this file to you under the Educational
* Community License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of the License
* at:
*
* http://opensource.org/licenses/ecl2.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*
*/
package org.opencastproject.search.impl;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.opencastproject.security.api.Permissions.Action.READ;
import static org.opencastproject.security.api.Permissions.Action.WRITE;
import static org.opencastproject.util.persistence.PersistenceUtil.newTestEntityManagerFactory;
import org.opencastproject.job.api.Job;
import org.opencastproject.job.api.Job.Status;
import org.opencastproject.job.api.JobBarrier;
import org.opencastproject.job.api.JobImpl;
import org.opencastproject.mediapackage.DefaultMediaPackageSerializerImpl;
import org.opencastproject.mediapackage.MediaPackage;
import org.opencastproject.mediapackage.MediaPackageBuilder;
import org.opencastproject.mediapackage.MediaPackageBuilderFactory;
import org.opencastproject.mediapackage.MediaPackageException;
import org.opencastproject.mediapackage.MediaPackageParser;
import org.opencastproject.mediapackage.identifier.IdBuilderFactory;
import org.opencastproject.metadata.api.StaticMetadataService;
import org.opencastproject.metadata.dublincore.DublinCoreCatalog;
import org.opencastproject.metadata.dublincore.DublinCores;
import org.opencastproject.metadata.dublincore.StaticMetadataServiceDublinCoreImpl;
import org.opencastproject.metadata.mpeg7.Mpeg7CatalogService;
import org.opencastproject.search.api.SearchQuery;
import org.opencastproject.search.api.SearchResult;
import org.opencastproject.search.api.SearchResultItem;
import org.opencastproject.search.impl.persistence.SearchServiceDatabaseImpl;
import org.opencastproject.search.impl.solr.SolrIndexManager;
import org.opencastproject.search.impl.solr.SolrRequester;
import org.opencastproject.security.api.AccessControlEntry;
import org.opencastproject.security.api.AccessControlList;
import org.opencastproject.security.api.AclScope;
import org.opencastproject.security.api.AuthorizationService;
import org.opencastproject.security.api.DefaultOrganization;
import org.opencastproject.security.api.JaxbOrganization;
import org.opencastproject.security.api.JaxbRole;
import org.opencastproject.security.api.JaxbUser;
import org.opencastproject.security.api.Organization;
import org.opencastproject.security.api.OrganizationDirectoryService;
import org.opencastproject.security.api.Permissions;
import org.opencastproject.security.api.SecurityService;
import org.opencastproject.security.api.User;
import org.opencastproject.security.api.UserDirectoryService;
import org.opencastproject.series.api.SeriesService;
import org.opencastproject.serviceregistry.api.IncidentService;
import org.opencastproject.serviceregistry.api.ServiceRegistry;
import org.opencastproject.serviceregistry.api.ServiceRegistryInMemoryImpl;
import org.opencastproject.util.data.Tuple;
import org.opencastproject.workspace.api.Workspace;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.solr.client.solrj.SolrServer;
import org.easymock.EasyMock;
import org.easymock.IAnswer;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.File;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Tests the functionality of the search service.
*
* todo setup scenario where gathering metadata from both the media package and the dublin core is required
* (StaticMetadataServiceMediaPackageImpl, StaticMetadataServiceDublinCoreImpl)
*/
public class SearchServiceImplTest {
/** The search service */
private SearchServiceImpl service = null;
/** Service registry */
private ServiceRegistry serviceRegistry = null;
/** The solr root directory */
private final String solrRoot = "target" + File.separator + "opencast" + File.separator + "searchindex";
/** The access control list returned by the mocked authorization service */
private AccessControlList acl = null;
/** The authorization service */
private AuthorizationService authorizationService = null;
/** Student role */
private static final String ROLE_STUDENT = "ROLE_STUDENT";
/** Other student role */
private static final String ROLE_OTHER_STUDENT = "ROLE_OTHER_STUDENT";
private final DefaultOrganization defaultOrganization = new DefaultOrganization();
/** A user with permissions. */
private final User userWithPermissions = new JaxbUser("sample", "test", defaultOrganization, new JaxbRole(
ROLE_STUDENT, defaultOrganization), new JaxbRole(ROLE_OTHER_STUDENT, defaultOrganization), new JaxbRole(
defaultOrganization.getAnonymousRole(), defaultOrganization));
/** A user without permissions. */
private final User userWithoutPermissions = new JaxbUser("sample", "test", defaultOrganization, new JaxbRole(
"ROLE_NOTHING", defaultOrganization), new JaxbRole(DefaultOrganization.DEFAULT_ORGANIZATION_ANONYMOUS,
defaultOrganization));
private final User defaultUser = userWithPermissions;
private Responder<User> userResponder;
private Responder<Organization> organizationResponder;
private SearchServiceDatabaseImpl searchDatabase;
private static class Responder<A> implements IAnswer<A> {
private A response;
Responder(A response) {
this.response = response;
}
public void setResponse(A response) {
this.response = response;
}
@Override
public A answer() throws Throwable {
return response;
}
}
@Before
public void setUp() throws Exception {
// workspace
Workspace workspace = EasyMock.createNiceMock(Workspace.class);
EasyMock.expect(workspace.get((URI) EasyMock.anyObject())).andAnswer(new IAnswer<File>() {
@Override
public File answer() throws Throwable {
return new File(new URI(EasyMock.getCurrentArguments()[0].toString()));
}
}).anyTimes();
EasyMock.replay(workspace);
// User, organization and service registry
userResponder = new Responder<User>(defaultUser);
organizationResponder = new Responder<Organization>(defaultOrganization);
SecurityService securityService = EasyMock.createNiceMock(SecurityService.class);
EasyMock.expect(securityService.getUser()).andAnswer(userResponder).anyTimes();
EasyMock.expect(securityService.getOrganization()).andAnswer(organizationResponder).anyTimes();
EasyMock.replay(securityService);
User anonymous = new JaxbUser("anonymous", "test", defaultOrganization, new JaxbRole(
DefaultOrganization.DEFAULT_ORGANIZATION_ANONYMOUS, defaultOrganization));
UserDirectoryService userDirectoryService = EasyMock.createMock(UserDirectoryService.class);
EasyMock.expect(userDirectoryService.loadUser((String) EasyMock.anyObject())).andReturn(anonymous).anyTimes();
EasyMock.replay(userDirectoryService);
Organization organization = new DefaultOrganization();
OrganizationDirectoryService organizationDirectoryService = EasyMock.createMock(OrganizationDirectoryService.class);
EasyMock.expect(organizationDirectoryService.getOrganization((String) EasyMock.anyObject()))
.andReturn(organization).anyTimes();
EasyMock.replay(organizationDirectoryService);
// mpeg7 service
Mpeg7CatalogService mpeg7CatalogService = new Mpeg7CatalogService();
// Persistence storage
searchDatabase = new SearchServiceDatabaseImpl();
searchDatabase.setEntityManagerFactory(newTestEntityManagerFactory(SearchServiceDatabaseImpl.PERSISTENCE_UNIT));
searchDatabase.activate(null);
searchDatabase.setSecurityService(securityService);
// search service
service = new SearchServiceImpl();
serviceRegistry = new ServiceRegistryInMemoryImpl(service, securityService, userDirectoryService,
organizationDirectoryService, EasyMock.createNiceMock(IncidentService.class));
StaticMetadataService mdService = newStaticMetadataService(workspace);
SeriesService seriesService = EasyMock.createNiceMock(SeriesService.class);
DublinCoreCatalog seriesCatalog = getSeriesDublinCoreCatalog("/series-dublincore.xml");
AccessControlList seriesAcl = new AccessControlList();
EasyMock.expect(seriesService.getSeries((String) EasyMock.anyObject())).andReturn(seriesCatalog).anyTimes();
EasyMock.expect(seriesService.getSeriesAccessControl((String) EasyMock.anyObject())).andReturn(seriesAcl)
.anyTimes();
EasyMock.replay(seriesService);
service.setStaticMetadataService(mdService);
service.setWorkspace(workspace);
service.setMpeg7CatalogService(mpeg7CatalogService);
service.setSecurityService(securityService);
service.setOrganizationDirectoryService(organizationDirectoryService);
service.setUserDirectoryService(userDirectoryService);
service.setServiceRegistry(serviceRegistry);
service.setPersistence(searchDatabase);
SolrServer solrServer = SearchServiceImpl.setupSolr(new File(solrRoot));
service.testSetup(solrServer, new SolrRequester(solrServer, securityService), new SolrIndexManager(solrServer,
workspace, Arrays.asList(mdService), seriesService, mpeg7CatalogService, securityService));
// acl
String anonymousRole = securityService.getOrganization().getAnonymousRole();
acl = new AccessControlList(new AccessControlEntry(anonymousRole, Permissions.Action.READ.toString(), true));
authorizationService = EasyMock.createNiceMock(AuthorizationService.class);
EasyMock.expect(authorizationService.getActiveAcl((MediaPackage) EasyMock.anyObject()))
.andReturn(Tuple.tuple(acl, AclScope.Series)).anyTimes();
EasyMock.expect(
authorizationService.hasPermission((MediaPackage) EasyMock.anyObject(), (String) EasyMock.anyObject()))
.andReturn(true).anyTimes();
service.setAuthorizationService(authorizationService);
EasyMock.replay(authorizationService);
}
private StaticMetadataService newStaticMetadataService(Workspace workspace) {
StaticMetadataServiceDublinCoreImpl service = new StaticMetadataServiceDublinCoreImpl();
service.setWorkspace(workspace);
return service;
}
private DublinCoreCatalog getSeriesDublinCoreCatalog(String path) {
// marshal the local series catalog
DublinCoreCatalog seriesDc = null;
InputStream is = null;
try {
is = SearchServiceImplTest.class.getResourceAsStream(path);
seriesDc = DublinCores.read(is);
} finally {
IOUtils.closeQuietly(is);
}
return seriesDc;
}
@After
public void tearDown() throws Exception {
((ServiceRegistryInMemoryImpl) serviceRegistry).dispose();
searchDatabase = null;
service.deactivate();
FileUtils.deleteDirectory(new File(solrRoot));
service = null;
}
/**
* Test whether an empty search index will work.
*/
@Test
public void testEmptySearchIndex() {
SearchResult result = service.getByQuery(new SearchQuery().withId("foo"));
assertEquals(0, result.size());
}
/**
* Adds a simple media package that has a dublin core for the episode only.
*/
@Test
public void testGetMediaPackage() throws Exception {
MediaPackage mediaPackage = getMediaPackage("/manifest-simple.xml");
// Make sure our mocked ACL has the read and write permission
acl.getEntries().add(new AccessControlEntry(ROLE_STUDENT, READ.toString(), true));
acl.getEntries().add(new AccessControlEntry(ROLE_STUDENT, WRITE.toString(), true));
// Add the media package to the search index
Job job = service.add(mediaPackage);
JobBarrier barrier = new JobBarrier(null, serviceRegistry, 1000, job);
barrier.waitForJobs();
assertEquals("Job to add mediapckage did not finish", Job.Status.FINISHED, job.getStatus());
// Make sure it's properly indexed and returned for authorized users
SearchQuery q = new SearchQuery();
q.includeEpisodes(true);
q.includeSeries(false);
q.withId("10.0000/1");
assertEquals(1, service.getByQuery(q).size());
acl.getEntries().clear();
acl.getEntries().add(new AccessControlEntry("ROLE_UNKNOWN", READ.toString(), true));
acl.getEntries().add(new AccessControlEntry(ROLE_STUDENT, WRITE.toString(), true));
// Add the media package to the search index
job = service.add(mediaPackage);
barrier = new JobBarrier(null, serviceRegistry, 1000, job);
barrier.waitForJobs();
assertEquals("Job to add mediapckage did not finish", Job.Status.FINISHED, job.getStatus());
// This mediapackage should not be readable by the current user (due to the lack of role ROLE_UNKNOWN)
q = new SearchQuery();
q.includeEpisodes(true);
q.includeSeries(false);
q.withId("10.0000/1");
assertEquals(0, service.getByQuery(q).size());
}
private MediaPackage getMediaPackage(String path) throws MediaPackageException {
MediaPackageBuilderFactory builderFactory = MediaPackageBuilderFactory.newInstance();
MediaPackageBuilder mediaPackageBuilder = builderFactory.newMediaPackageBuilder();
URL rootUrl = SearchServiceImplTest.class.getResource("/");
mediaPackageBuilder.setSerializer(new DefaultMediaPackageSerializerImpl(rootUrl));
// Load the simple media package
MediaPackage mediaPackage = null;
InputStream is = null;
try {
is = SearchServiceImplTest.class.getResourceAsStream(path);
mediaPackage = mediaPackageBuilder.loadFromXml(is);
} finally {
IOUtils.closeQuietly(is);
}
return mediaPackage;
}
/**
* Tests whether an episode can be found based on its series metadata.
*/
@Test
public void testSearchForEpisodeWithSeriesMetadata() throws Exception {
MediaPackage mediaPackage = getMediaPackage("/manifest-full.xml");
Job job = service.add(mediaPackage);
JobBarrier barrier = new JobBarrier(null, serviceRegistry, 1000, job);
barrier.waitForJobs();
assertEquals("Job to add mediapckage did not finish", Job.Status.FINISHED, job.getStatus());
SearchResult episodeMetadataResult = service.getByQuery(new SearchQuery().withText("Vegetation"));
SearchResult seriesMetadataResult = service.getByQuery(new SearchQuery().withText("Atmospheric Science"));
assertEquals(1, service.getByQuery(new SearchQuery().withText("Atmospheric")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("atmospheric")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("atmospheric science")).size());
assertEquals(1, episodeMetadataResult.getItems().length);
assertEquals(1, seriesMetadataResult.getItems().length);
}
@Test
public void testSearchForPartialStrings() throws Exception {
MediaPackage mediaPackage = getMediaPackage("/manifest-simple.xml");
Job job = service.add(mediaPackage);
JobBarrier barrier = new JobBarrier(null, serviceRegistry, 1000, job);
barrier.waitForJobs();
assertEquals("Job to add mediapckage did not finish", Job.Status.FINISHED, job.getStatus());
assertEquals(1, service.getByQuery(new SearchQuery().withText("Atmo")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("Atmos")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("Atmosp")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("Atmosph")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("Atmosphe")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("Atmospher")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("Atmospheri")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("Atmospheric")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("atmospheri")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("tmospheric")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("tmospheri")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("Vegetatio")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("vege")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("egetatio")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("egetation")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("lecture")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("lectur")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("ecture")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("ectur")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("Science")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("Scienc")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("ience")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("cienc")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("ducti")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("Institute")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("nstitute")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("nstitut")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("Institut")).size());
assertEquals(1, service.getByQuery(new SearchQuery().withText("2008-03-05")).size());
}
@Test
public void testSorting() throws Exception {
MediaPackage mediaPackageNewer = getMediaPackage("/manifest-full.xml");
MediaPackage mediaPackageOlder = getMediaPackage("/manifest-full-older.xml");
// MH-10573, ensure first job finishes publishing before job2
Job job = service.add(mediaPackageNewer);
JobBarrier barrier = new JobBarrier(null, serviceRegistry, 1000, job);
barrier.waitForJobs();
Job job2 = service.add(mediaPackageOlder);
JobBarrier barrier2 = new JobBarrier(null,serviceRegistry, 1000, job2);
barrier2.waitForJobs();
String olderTitle = "Older Recording";
String newerTitle = "Land and Vegetation: Key players on the Climate Scene";
SearchQuery query = new SearchQuery();
query.withSort(SearchQuery.Sort.DATE_CREATED);
assertEquals(2, service.getByQuery(query).size());
assertEquals(olderTitle, service.getByQuery(query).getItems()[0].getDcTitle());
query.withSort(SearchQuery.Sort.DATE_CREATED, false);
assertEquals(newerTitle, service.getByQuery(query).getItems()[0].getDcTitle());
// FYI: DATE_PUBLISHED is the time of Search update, not DC modified (MH-10573)
query.withSort(SearchQuery.Sort.DATE_PUBLISHED);
assertEquals(newerTitle, service.getByQuery(query).getItems()[0].getDcTitle());
query.withSort(SearchQuery.Sort.DATE_PUBLISHED, false);
assertEquals(olderTitle, service.getByQuery(query).getItems()[0].getDcTitle());
SearchQuery q = new SearchQuery();
q.withSort(SearchQuery.Sort.TITLE);
assertEquals(newerTitle, service.getByQuery(q).getItems()[0].getDcTitle());
query.withSort(SearchQuery.Sort.TITLE, false);
assertEquals(2, service.getByQuery(q).size());
assertEquals(olderTitle, service.getByQuery(query).getItems()[0].getDcTitle());
query.withSort(SearchQuery.Sort.LICENSE);
assertEquals(2, service.getByQuery(query).size()); // Just checking that the search index works for this field
query.withSort(SearchQuery.Sort.SERIES_ID);
assertEquals(2, service.getByQuery(query).size()); // Just checking that the search index works for this field
query.withSort(SearchQuery.Sort.MEDIA_PACKAGE_ID);
assertEquals(2, service.getByQuery(query).size()); // Just checking that the search index works for this field
query.withSort(SearchQuery.Sort.CONTRIBUTOR);
assertEquals(2, service.getByQuery(query).size()); // Just checking that the search index works for this field
query.withSort(SearchQuery.Sort.CREATOR);
assertEquals(2, service.getByQuery(query).size()); // Just checking that the search index works for this field
query.withSort(SearchQuery.Sort.LANGUAGE);
assertEquals(2, service.getByQuery(query).size()); // Just checking that the search index works for this field
query.withSort(SearchQuery.Sort.SUBJECT);
assertEquals(2, service.getByQuery(query).size()); // Just checking that the search index works for this field
}
/**
* Adds a simple media package that has a dublin core for the episode only.
*/
@Test
public void testAddSimpleMediaPackage() throws Exception {
MediaPackage mediaPackage = getMediaPackage("/manifest-simple.xml");
// Make sure our mocked ACL has the read and write permission
acl.getEntries().add(new AccessControlEntry(ROLE_STUDENT, READ.toString(), true));
acl.getEntries().add(new AccessControlEntry(ROLE_STUDENT, WRITE.toString(), true));
// Add the media package to the search index
Job job = service.add(mediaPackage);
JobBarrier barrier = new JobBarrier(null, serviceRegistry, 1000, job);
barrier.waitForJobs();
assertEquals("Job to add mediapckage did not finish", Job.Status.FINISHED, job.getStatus());
// Make sure it's properly indexed and returned
SearchQuery q = new SearchQuery();
q.includeEpisodes(true);
q.includeSeries(false);
q.withId("10.0000/1");
assertEquals(1, service.getByQuery(q).size());
q = new SearchQuery();
q.includeEpisodes(true);
q.includeSeries(false);
assertEquals(1, service.getByQuery(q).size());
// Test for various fields
q = new SearchQuery();
q.includeEpisodes(true);
q.includeSeries(false);
q.withId("10.0000/1");
SearchResult result = service.getByQuery(q);
assertEquals(1, result.getTotalSize());
SearchResultItem resultItem = result.getItems()[0];
assertNotNull(resultItem.getMediaPackage());
assertEquals(1, resultItem.getMediaPackage().getCatalogs().length);
}
/**
* Ads a simple media package that has a dublin core for the episode only.
*/
@Test
public void testAddFullMediaPackage() throws Exception {
MediaPackage mediaPackage = getMediaPackage("/manifest-full.xml");
// Make sure our mocked ACL has the read and write permission
acl.getEntries().add(new AccessControlEntry(ROLE_STUDENT, READ.toString(), true));
acl.getEntries().add(new AccessControlEntry(ROLE_STUDENT, WRITE.toString(), true));
// Add the media package to the search index
Job job = service.add(mediaPackage);
JobBarrier barrier = new JobBarrier(null, serviceRegistry, 1000, job);
barrier.waitForJobs();
assertEquals("Job to add mediapckage did not finish", Job.Status.FINISHED, job.getStatus());
// Make sure it's properly indexed and returned
SearchQuery q = new SearchQuery();
q.includeEpisodes(true);
q.includeSeries(false);
q.withId("10.0000/2");
assertEquals(1, service.getByQuery(q).size());
q.withId(null); // Clear the ID requirement
assertEquals(1, service.getByQuery(q).size());
}
/**
* Test removal from the search index.
*/
@Test
public void testDeleteMediaPackage() throws Exception {
MediaPackage mediaPackage = getMediaPackage("/manifest-simple.xml");
// Make sure our mocked ACL has the read and write permission
acl.getEntries().add(new AccessControlEntry(ROLE_STUDENT, READ.toString(), true));
acl.getEntries().add(new AccessControlEntry(ROLE_STUDENT, WRITE.toString(), true));
// Add the media package to the search index
Job job = service.add(mediaPackage);
JobBarrier barrier = new JobBarrier(null, serviceRegistry, 1000, job);
barrier.waitForJobs();
// Now take the role away from the user
userResponder.setResponse(userWithoutPermissions);
Map<String, Integer> servers = new HashMap<String, Integer>();
servers.put("http://localhost", 8080);
organizationResponder.setResponse(new JaxbOrganization(DefaultOrganization.DEFAULT_ORGANIZATION_ID,
DefaultOrganization.DEFAULT_ORGANIZATION_NAME, servers, DefaultOrganization.DEFAULT_ORGANIZATION_ADMIN,
DefaultOrganization.DEFAULT_ORGANIZATION_ANONYMOUS, null));
// Try to delete it
job = service.delete(mediaPackage.getIdentifier().toString());
barrier = new JobBarrier(null, serviceRegistry, 1000, job);
barrier.waitForJobs();
assertEquals("Job to delete mediapackage did not finish", Job.Status.FINISHED, job.getStatus());
assertEquals("Unauthorized user was able to delete a mediapackage", Boolean.FALSE.toString(),
job.getPayload());
// Second try with a "fixed" roleset
User adminUser = new JaxbUser("admin", "test", defaultOrganization, new JaxbRole(
defaultOrganization.getAdminRole(), defaultOrganization));
userResponder.setResponse(adminUser);
Date deletedDate = new Date();
job = service.delete(mediaPackage.getIdentifier().toString());
barrier = new JobBarrier(null, serviceRegistry, 1000, job);
barrier.waitForJobs();
assertEquals("Unauthorized user was able to delete a mediapackage", Job.Status.FINISHED, job.getStatus());
// Now go back to the original security service and user
userResponder.setResponse(defaultUser);
organizationResponder.setResponse(defaultOrganization);
SearchQuery q = new SearchQuery();
q.includeEpisodes(true);
q.includeSeries(false);
q.withId("10.0000/1");
assertEquals(0, service.getByQuery(q).size());
q.withId(null); // Clear the ID requirement
assertEquals(0, service.getByQuery(q).size());
q = new SearchQuery();
q.withDeletedSince(deletedDate);
assertEquals(1, service.getByQuery(q).size());
}
/**
* Test removal from the search index even when it is missing from database #MH-11616
*/
@Test
public void testDeleteIndexNotInDbMediaPackage() throws Exception {
MediaPackage mediaPackage = getMediaPackage("/manifest-simple.xml");
// Make sure our mocked ACL has the read and write permission
acl.getEntries().add(new AccessControlEntry(ROLE_STUDENT, READ.toString(), true));
acl.getEntries().add(new AccessControlEntry(ROLE_STUDENT, WRITE.toString(), true));
// Add the media package to the search index
Job job = service.add(mediaPackage);
JobBarrier barrier = new JobBarrier(null, serviceRegistry, 1000, job);
barrier.waitForJobs();
// Delete the mediapackage from persistence (leave it in index)
Date dateDeletedFromDb = new Date();
searchDatabase.deleteMediaPackage(mediaPackage.getIdentifier().toString(), dateDeletedFromDb);
// Verify it is not marked as deleted
SearchQuery qDel = new SearchQuery();
qDel.withDeletedSince(dateDeletedFromDb);
assertEquals(0, service.getByQuery(qDel).size());
// Verify that it is still active in index
SearchQuery q = new SearchQuery();
q.includeEpisodes(true);
q.includeSeries(false);
q.withId(mediaPackage.getIdentifier().toString());
assertEquals(1, service.getByQuery(q).size());
// Try delete it
job = service.delete(mediaPackage.getIdentifier().toString());
barrier = new JobBarrier(null, serviceRegistry, 1000, job);
barrier.waitForJobs();
assertEquals("Job to delete mediapackage did not finish", Job.Status.FINISHED, job.getStatus());
// Verify that it is now not active in the index
assertEquals(0, service.getByQuery(q).size());
// Verify that it is now marked as deleted in the index
q = new SearchQuery();
q.withDeletedSince(dateDeletedFromDb);
assertEquals(1, service.getByQuery(q).size());
}
/**
* Adds a media package with a dublin core catalog for episode and series. Verifies series catalog can be retrieved
* via search service.
*
*/
@Test
public void testAddSeriesMediaPackage() throws Exception {
String seriesId = "foobar-series";
MediaPackage mediaPackage = getMediaPackage("/manifest-full.xml");
mediaPackage.setSeries(seriesId);
// Add the media package to the search index
Job job = service.add(mediaPackage);
JobBarrier barrier = new JobBarrier(null, serviceRegistry, 1000, job);
barrier.waitForJobs();
assertEquals("Job to add mediapckage did not finish", Job.Status.FINISHED, job.getStatus());
User adminUser = new JaxbUser("admin", "test", defaultOrganization,
new JaxbRole(defaultOrganization.getAdminRole(), defaultOrganization));
userResponder.setResponse(adminUser);
// Make sure it's properly indexed and returned
SearchQuery q = new SearchQuery();
q.includeEpisodes(false);
q.includeSeries(true);
SearchResult result = service.getByQuery(q);
assertEquals(1, result.size());
assertEquals(seriesId, result.getItems()[0].getId());
}
@SuppressWarnings("unchecked")
@Test
public void testPopulateIndex() throws Exception {
// This service registry must return a list of jobs
List<String> args = new ArrayList<String>();
args.add(new DefaultOrganization().getId());
List<Job> jobs = new ArrayList<Job>();
for (long i = 0; i < 10; i++) {
MediaPackage mediaPackage = MediaPackageBuilderFactory.newInstance().newMediaPackageBuilder().createNew();
mediaPackage.setIdentifier(IdBuilderFactory.newInstance().newIdBuilder().createNew());
searchDatabase.storeMediaPackage(mediaPackage, acl, new Date());
String payload = MediaPackageParser.getAsXml(mediaPackage);
Job job = new JobImpl(i);
job.setArguments(args);
job.setPayload(payload);
job.setStatus(Status.FINISHED);
jobs.add(job);
}
ServiceRegistry serviceRegistry = EasyMock.createNiceMock(ServiceRegistry.class);
EasyMock.expect(
serviceRegistry.createJob((String) EasyMock.anyObject(), (String) EasyMock.anyObject(),
(List<String>) EasyMock.anyObject(), (String) EasyMock.anyObject(), EasyMock.anyBoolean()))
.andReturn(new JobImpl()).anyTimes();
EasyMock.expect(serviceRegistry.updateJob((Job) EasyMock.anyObject())).andReturn(new JobImpl()).anyTimes();
EasyMock.expect(serviceRegistry.getJobs((String) EasyMock.anyObject(), (Status) EasyMock.anyObject()))
.andReturn(jobs).anyTimes();
EasyMock.replay(serviceRegistry);
service.setServiceRegistry(serviceRegistry);
OrganizationDirectoryService orgDirectory = EasyMock.createNiceMock(OrganizationDirectoryService.class);
EasyMock.expect(orgDirectory.getOrganization((String) EasyMock.anyObject())).andReturn(new DefaultOrganization())
.anyTimes();
EasyMock.replay(orgDirectory);
service.setOrganizationDirectoryService(orgDirectory);
// We should have nothing in the search index
assertEquals(0, service.getByQuery(new SearchQuery()).size());
service.populateIndex("System Admin");
// This time we should have 10 results
assertEquals(10, service.getByQuery(new SearchQuery()).size());
}
}