/** * 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.distribution.streaming; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.opencastproject.util.UrlSupport.concat; import org.opencastproject.job.api.Job; import org.opencastproject.job.api.JobBarrier; import org.opencastproject.mediapackage.MediaPackage; import org.opencastproject.mediapackage.MediaPackageElementParser; import org.opencastproject.mediapackage.MediaPackageParser; import org.opencastproject.security.api.DefaultOrganization; import org.opencastproject.security.api.JaxbRole; import org.opencastproject.security.api.JaxbUser; import org.opencastproject.security.api.OrganizationDirectoryService; import org.opencastproject.security.api.SecurityService; import org.opencastproject.security.api.User; import org.opencastproject.security.api.UserDirectoryService; import org.opencastproject.serviceregistry.api.IncidentService; import org.opencastproject.serviceregistry.api.ServiceRegistry; import org.opencastproject.serviceregistry.api.ServiceRegistryInMemoryImpl; import org.opencastproject.util.PathSupport; import org.opencastproject.util.data.Option; import org.opencastproject.workspace.api.Workspace; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.easymock.EasyMock; import org.easymock.IAnswer; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.osgi.framework.BundleContext; import org.osgi.service.component.ComponentContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.net.URI; public class StreamingDistributionServiceTest { private static final Logger logger = LoggerFactory.getLogger(StreamingDistributionServiceTest.class); private StreamingDistributionService service = null; private MediaPackage mp = null; private File distributionRoot = null; private ServiceRegistry serviceRegistry = null; private DefaultOrganization defaultOrganization; @Rule public TemporaryFolder testFolder = new TemporaryFolder(); @Before public void setUp() throws Exception { final File mediaPackageRoot = new File(getClass().getResource("/mediapackage.xml").toURI()).getParentFile(); mp = MediaPackageParser.getFromXml(IOUtils.toString(getClass().getResourceAsStream("/mediapackage.xml"), "UTF-8")); distributionRoot = new File(mediaPackageRoot, "static"); service = new StreamingDistributionService(); defaultOrganization = new DefaultOrganization(); 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); service.setUserDirectoryService(userDirectoryService); OrganizationDirectoryService organizationDirectoryService = EasyMock.createMock(OrganizationDirectoryService.class); EasyMock.expect(organizationDirectoryService.getOrganization((String) EasyMock.anyObject())) .andReturn(defaultOrganization).anyTimes(); EasyMock.replay(organizationDirectoryService); service.setOrganizationDirectoryService(organizationDirectoryService); SecurityService securityService = EasyMock.createNiceMock(SecurityService.class); EasyMock.expect(securityService.getUser()).andReturn(anonymous).anyTimes(); EasyMock.expect(securityService.getOrganization()).andReturn(defaultOrganization).anyTimes(); EasyMock.replay(securityService); service.setSecurityService(securityService); serviceRegistry = new ServiceRegistryInMemoryImpl(service, securityService, userDirectoryService, organizationDirectoryService, EasyMock.createNiceMock(IncidentService.class)); service.setServiceRegistry(serviceRegistry); final Workspace workspace = EasyMock.createNiceMock(Workspace.class); EasyMock.expect(workspace.get((URI) EasyMock.anyObject())).andAnswer(new IAnswer<File>() { @Override public File answer() throws Throwable { final URI uri = (URI) EasyMock.getCurrentArguments()[0]; final String[] pathElems = uri.getPath().split("/"); final String file = pathElems[pathElems.length - 1]; return new File(mediaPackageRoot, file); } }).anyTimes(); EasyMock.replay(workspace); service.setWorkspace(workspace); BundleContext bc = EasyMock.createNiceMock(BundleContext.class); EasyMock.expect(bc.getProperty("org.opencastproject.streaming.url")).andReturn("rtmp://localhost/").anyTimes(); EasyMock.expect(bc.getProperty("org.opencastproject.streaming.directory")).andReturn(distributionRoot.getPath()) .anyTimes(); EasyMock.replay(bc); ComponentContext cc = EasyMock.createNiceMock(ComponentContext.class); EasyMock.expect(cc.getBundleContext()).andReturn(bc).anyTimes(); EasyMock.replay(cc); service.activate(cc); } @After public void tearDown() throws Exception { FileUtils.deleteDirectory(distributionRoot); ((ServiceRegistryInMemoryImpl) serviceRegistry).dispose(); } @Test public void testUriFileConversionFlvWorkspace() throws Exception { final StreamingDistributionService.Locations loc = new StreamingDistributionService.Locations( URI.create("rtmp://localhost/matterhorn-engage"), testFolder.newFolder(), false); final String channelId = "engage-player"; final String mpId = "9f411edb-edf5-4308-8df5-f9b111d9d346"; final String mpeId = "bed1cdba-2d42-49b1-b78f-6c6745fb064a"; final URI mpeUri = URI .create(concat("http://localhost:8080/files/mediapackage/", mpId, mpeId, "hans_arp_1m10s.flv")); // final URI distUri = loc.createDistributionUri(defaultOrganization.getId(), channelId, mpId, mpeId, mpeUri); logger.info(distUri.toString()); assertTrue("original URI and distribution URI are not equal", !distUri.equals(mpeUri)); final File distFile = loc.createDistributionFile(defaultOrganization.getId(), channelId, mpId, mpeId, mpeUri); logger.info(distFile.toString()); final Option<File> retrievedFile = loc.getDistributionFileFrom(distUri); logger.info(retrievedFile.toString()); assertTrue("file could be retrieved from distribution URI", retrievedFile.isSome()); assertEquals("file retrieved from distribution URI and distribution file match", distFile, retrievedFile.get()); } @Test public void testUriFileConversionFlvDistribution() throws Exception { final StreamingDistributionService.Locations loc = new StreamingDistributionService.Locations( URI.create("rtmp://localhost/matterhorn-engage"), testFolder.newFolder(), false); final String channelId = "engage-player"; final String mpId = "9f411edb-edf5-4308-8df5-f9b111d9d346"; final String mpeId = "bed1cdba-2d42-49b1-b78f-6c6745fb064a"; final URI mpeUri = URI.create( concat("rtmp://localhost/matterhorn-engage/mh_default_org/", channelId, mpId, mpeId, "Hans_Arp_1m10s")); // final URI distUri = loc.createDistributionUri(defaultOrganization.getId(), channelId, mpId, mpeId, mpeUri); logger.info(distUri.toString()); assertEquals("original URI and distribution URI are equal", distUri, mpeUri); final File distFile = loc.createDistributionFile(defaultOrganization.getId(), channelId, mpId, mpeId, mpeUri); logger.info(distFile.toString()); final Option<File> retrievedFile = loc.getDistributionFileFrom(distUri); logger.info(retrievedFile.toString()); assertTrue("file could be retrieved from distribution URI", retrievedFile.isSome()); assertEquals("file retrieved from distribution URI and distribution file match", distFile, retrievedFile.get()); } @Test public void testUriFileConversionMp4Workspace() throws Exception { final StreamingDistributionService.Locations loc = new StreamingDistributionService.Locations( URI.create("rtmp://localhost/matterhorn-engage"), testFolder.newFolder(), false); final String channelId = "engage-player"; final String mpId = "9f411edb-edf5-4308-8df5-f9b111d9d346"; final String mpeId = "bed1cdba-2d42-49b1-b78f-6c6745fb064a"; final URI mpeUri = URI .create(concat("http://localhost:8080/files/mediapackage/", mpId, mpeId, "hans_arp_1m10s.mp4")); // final URI distUri = loc.createDistributionUri(defaultOrganization.getId(), channelId, mpId, mpeId, mpeUri); logger.info(distUri.toString()); assertTrue("original URI and distribution URI are not equal", !distUri.equals(mpeUri)); final File distFile = loc.createDistributionFile(defaultOrganization.getId(), channelId, mpId, mpeId, mpeUri); logger.info(distFile.toString()); final Option<File> retrievedFile = loc.getDistributionFileFrom(distUri); logger.info(retrievedFile.toString()); assertTrue("file could be retrieved from distribution URI", retrievedFile.isSome()); assertEquals("file retrieved from distribution URI and distribution file match", distFile, retrievedFile.get()); } @Test public void testUriFileConversionMp4Distribution() throws Exception { final StreamingDistributionService.Locations loc = new StreamingDistributionService.Locations( URI.create("rtmp://localhost/matterhorn-engage"), testFolder.newFolder(), false); final String channelId = "engage-player"; final String mpId = "9f411edb-edf5-4308-8df5-f9b111d9d346"; final String mpeId = "bed1cdba-2d42-49b1-b78f-6c6745fb064a"; final URI mpeUri = URI.create( concat("rtmp://localhost/matterhorn-engage/mp4:mh_default_org/", channelId, mpId, mpeId, "Hans_Arp_1m10s")); // final URI distUri = loc.createDistributionUri(defaultOrganization.getId(), channelId, mpId, mpeId, mpeUri); logger.info(distUri.toString()); assertEquals("original URI and distribution URI are equal", distUri, mpeUri); final File distFile = loc.createDistributionFile(defaultOrganization.getId(), channelId, mpId, mpeId, mpeUri); logger.info(distFile.toString()); final Option<File> retrievedFile = loc.getDistributionFileFrom(distUri); logger.info(retrievedFile.toString()); assertTrue("file could be retrieved from distribution URI", retrievedFile.isSome()); assertEquals("file retrieved from distribution URI and distribution file match", distFile, retrievedFile.get()); } @Test public void testUriFileRetrieval() throws Exception { File testDir = testFolder.newFolder(); final StreamingDistributionService.Locations loc1 = new StreamingDistributionService.Locations( URI.create("rtmp://localhost/matterhorn-engage"), testDir, false); final StreamingDistributionService.Locations loc2 = new StreamingDistributionService.Locations( URI.create("rtmp://localhost/matterhorn-engage/"), testDir, false); final String channelId = "engage-player"; final String mpId = "9f411edb-edf5-4308-8df5-f9b111d9d346"; final String mpeId = "bed1cdba-2d42-49b1-b78f-6c6745fb064a"; final URI distUri = URI.create( concat("rtmp://localhost/matterhorn-engage/mp4:mh_default_org/", channelId, mpId, mpeId, "Hans_Arp_1m10s")); // final Option<File> retrievedFile1 = loc1.getDistributionFileFrom(distUri); final Option<File> retrievedFile2 = loc2.getDistributionFileFrom(distUri); assertTrue("file could be retrieved from distribution URI", retrievedFile1.isSome()); assertTrue("file could be retrieved from distribution URI", retrievedFile2.isSome()); assertEquals(retrievedFile1, retrievedFile2); } @Test public void testDistribution() throws Exception { // Distribute the mediapackage and all of its elements Job job1 = service.distribute("engage-player", mp, "track-1"); Job job2 = service.distribute("oai-pmh", mp, "track-1"); JobBarrier jobBarrier = new JobBarrier(null, serviceRegistry, 500, job1, job2); jobBarrier.waitForJobs(); // Add the new elements to the mediapackage mp.add(MediaPackageElementParser.getFromXml(job1.getPayload())); mp.add(MediaPackageElementParser.getFromXml(job2.getPayload())); File mpDir = new File(distributionRoot, PathSupport.path(defaultOrganization.getId(), "engage-player", mp.getIdentifier().compact())); File mediaDir = new File(mpDir, "track-1"); Assert.assertTrue(mediaDir.exists()); Assert.assertTrue(new File(mediaDir, "media.mov").exists()); // the filenames are changed to reflect the element ID } }