/**
* 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.workspace.impl;
import org.opencastproject.security.api.TrustedHttpClient;
import org.opencastproject.security.api.TrustedHttpClient.RequestRunner;
import org.opencastproject.security.util.StandAloneTrustedHttpClientImpl;
import org.opencastproject.util.NotFoundException;
import org.opencastproject.util.PathSupport;
import org.opencastproject.util.UrlSupport;
import org.opencastproject.util.data.Either;
import org.opencastproject.util.data.Function;
import org.opencastproject.util.data.Option;
import org.opencastproject.workingfilerepository.api.WorkingFileRepository;
import com.entwinemedia.fn.Prelude;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.methods.HttpUriRequest;
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 java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import javax.servlet.http.HttpServletResponse;
public class WorkspaceImplTest {
private WorkspaceImpl workspace;
private static final String workspaceRoot = "." + File.separator + "target" + File.separator
+ "junit-workspace-rootdir";
private static final String repoRoot = "." + File.separator + "target" + File.separator + "junit-repo-rootdir";
@Rule
public TemporaryFolder testFolder = new TemporaryFolder();
@Before
public void setUp() throws Exception {
workspace = new WorkspaceImpl(workspaceRoot, false);
workspace.activate(null);
}
@After
public void tearDown() throws Exception {
workspace.deactivate();
FileUtils.deleteDirectory(new File(workspaceRoot));
FileUtils.deleteDirectory(new File(repoRoot));
}
@Test
public void testLongFilenames() throws Exception {
WorkingFileRepository repo = EasyMock.createNiceMock(WorkingFileRepository.class);
EasyMock.expect(repo.getBaseUri()).andReturn(new URI("http://localhost:8080/files")).anyTimes();
EasyMock.replay(repo);
workspace.setRepository(repo);
File source = new File(
"target/test-classes/../test-classes/../test-classes/../test-classes/../test-classes/../test-classes/../test-classes/../test-classes/../test-classes/../test-classes/../test-classes/../test-classes/../test-classes/../test-classes/../test-classes/../test-classes/opencast_header.gif");
URL urlToSource = source.toURI().toURL();
final TrustedHttpClient httpClient = EasyMock.createNiceMock(TrustedHttpClient.class);
HttpEntity entity = EasyMock.createNiceMock(HttpEntity.class);
EasyMock.expect(entity.getContent()).andReturn(new FileInputStream(source));
StatusLine statusLine = EasyMock.createNiceMock(StatusLine.class);
EasyMock.expect(statusLine.getStatusCode()).andReturn(HttpServletResponse.SC_OK);
HttpResponse response = EasyMock.createNiceMock(HttpResponse.class);
EasyMock.expect(response.getEntity()).andReturn(entity);
EasyMock.expect(response.getStatusLine()).andReturn(statusLine).anyTimes();
EasyMock.replay(response, entity, statusLine);
EasyMock.expect(httpClient.execute((HttpUriRequest) EasyMock.anyObject())).andReturn(response);
EasyMock.expect(httpClient.runner((HttpUriRequest) EasyMock.anyObject())).andAnswer(
new IAnswer<TrustedHttpClient.RequestRunner<Object>>() {
@Override
public RequestRunner<Object> answer() throws Throwable {
HttpUriRequest req = (HttpUriRequest) EasyMock.getCurrentArguments()[0];
return StandAloneTrustedHttpClientImpl.runner(httpClient, req);
}
});
EasyMock.replay(httpClient);
workspace.setTrustedHttpClient(httpClient);
Assert.assertTrue(urlToSource.toString().length() > 255);
try {
Assert.assertNotNull(workspace.get(urlToSource.toURI()));
} catch (NotFoundException e) {
// This happens on some machines, so we catch and handle it.
}
}
// Calls to put() should put the file into the working file repository, but not in the local cache if there's a valid
// filesystem mapping present
@Test
public void testPutCachingWithFilesystemMapping() throws Exception {
WorkingFileRepository repo = EasyMock.createNiceMock(WorkingFileRepository.class);
EasyMock.expect(
repo.getURI((String) EasyMock.anyObject(), (String) EasyMock.anyObject(), (String) EasyMock.anyObject()))
.andReturn(
new URI("http://localhost:8080/files" + WorkingFileRepository.MEDIAPACKAGE_PATH_PREFIX
+ "foo/bar/header.gif"));
EasyMock.expect(
repo.put((String) EasyMock.anyObject(), (String) EasyMock.anyObject(), (String) EasyMock.anyObject(),
(InputStream) EasyMock.anyObject())).andReturn(
new URI("http://localhost:8080/files" + WorkingFileRepository.MEDIAPACKAGE_PATH_PREFIX
+ "foo/bar/header.gif"));
EasyMock.expect(repo.getBaseUri()).andReturn(new URI("http://localhost:8080/files")).anyTimes();
EasyMock.replay(repo);
workspace.setRepository(repo);
// Put a stream into the workspace (and hence, the repository)
InputStream in = null;
try {
in = getClass().getResourceAsStream("/opencast_header.gif");
Assert.assertNotNull(in);
workspace.put("foo", "bar", "header.gif", in);
} finally {
IOUtils.closeQuietly(in);
}
// Ensure that the file was put into the working file repository
EasyMock.verify(repo);
// Ensure that the file was not cached in the workspace (since there is a configured filesystem mapping)
File file = new File(workspaceRoot, "http___localhost_8080_files_foo_bar_header.gif");
Assert.assertFalse(file.exists());
}
// Calls to put() should put the file into the working file repository and the local cache if there is no valid
// filesystem mapping present
@Test
public void testPutCachingWithoutFilesystemMapping() throws Exception {
// First, mock up the collaborating working file repository
WorkingFileRepository repo = EasyMock.createMock(WorkingFileRepository.class);
EasyMock.expect(
repo.getURI((String) EasyMock.anyObject(), (String) EasyMock.anyObject(), (String) EasyMock.anyObject()))
.andReturn(
new URI(UrlSupport.concat(new String[] { "http://localhost:8080", WorkingFileRepository.URI_PREFIX,
WorkingFileRepository.MEDIAPACKAGE_PATH_PREFIX, "foo", "bar", "header.gif" })));
EasyMock.expect(
repo.put((String) EasyMock.anyObject(), (String) EasyMock.anyObject(), (String) EasyMock.anyObject(),
(InputStream) EasyMock.anyObject())).andReturn(
new URI("http://localhost:8080/files" + WorkingFileRepository.MEDIAPACKAGE_PATH_PREFIX
+ "foo/bar/header.gif"));
EasyMock.expect(repo.getBaseUri()).andReturn(new URI("http://localhost:8080/files")).anyTimes();
EasyMock.replay(repo);
workspace.setRepository(repo);
// Put a stream into the workspace (and hence, the repository)
InputStream in = null;
try {
in = getClass().getResourceAsStream("/opencast_header.gif");
Assert.assertNotNull(in);
workspace.put("foo", "bar", "header.gif", in);
} finally {
IOUtils.closeQuietly(in);
}
// Ensure that the file was put into the working file repository
EasyMock.verify(repo);
// Ensure that the file was cached in the workspace (since there is no configured filesystem mapping)
File file = new File(PathSupport.concat(new String[] { workspaceRoot,
WorkingFileRepository.MEDIAPACKAGE_PATH_PREFIX, "foo", "bar", "header.gif" }));
Assert.assertTrue(file.exists());
}
@Test
public void testGetWorkspaceFileWithOutPort() throws Exception {
WorkingFileRepository repo = EasyMock.createNiceMock(WorkingFileRepository.class);
EasyMock.expect(repo.getBaseUri()).andReturn(new URI("http://localhost/files")).anyTimes();
EasyMock.replay(repo);
workspace.setRepository(repo);
File workspaceFile = workspace.toWorkspaceFile(new URI("http://foo.com/myaccount/videos/bar.mov"));
File expected = new File(PathSupport.concat(new String[] { workspaceRoot, "http_foo.com", "myaccount", "videos",
"bar.mov" }));
Assert.assertEquals(expected.getAbsolutePath(), workspaceFile.getAbsolutePath());
workspaceFile = workspace.toWorkspaceFile(new URI("http://foo.com:8080/myaccount/videos/bar.mov"));
expected = new File(PathSupport.concat(new String[] { workspaceRoot, "http_foo.com_8080", "myaccount", "videos",
"bar.mov" }));
Assert.assertEquals(expected.getAbsolutePath(), workspaceFile.getAbsolutePath());
workspaceFile = workspace.toWorkspaceFile(new URI("http://localhost/files/collection/c1/bar.mov"));
expected = new File(PathSupport.concat(new String[] { workspaceRoot, "collection", "c1", "bar.mov" }));
Assert.assertEquals(expected.getAbsolutePath(), workspaceFile.getAbsolutePath());
}
@Test
public void testGetWorkspaceFileWithPort() throws Exception {
WorkingFileRepository repo = EasyMock.createNiceMock(WorkingFileRepository.class);
EasyMock.expect(repo.getBaseUri()).andReturn(new URI("http://localhost:8080/files")).anyTimes();
EasyMock.replay(repo);
workspace.setRepository(repo);
File workspaceFile = workspace.toWorkspaceFile(new URI("http://foo.com/myaccount/videos/bar.mov"));
File expected = new File(PathSupport.concat(new String[] { workspaceRoot, "http_foo.com", "myaccount", "videos",
"bar.mov" }));
Assert.assertEquals(expected.getAbsolutePath(), workspaceFile.getAbsolutePath());
workspaceFile = workspace.toWorkspaceFile(new URI("http://foo.com:8080/myaccount/videos/bar.mov"));
expected = new File(PathSupport.concat(new String[] { workspaceRoot, "http_foo.com_8080", "myaccount", "videos",
"bar.mov" }));
Assert.assertEquals(expected.getAbsolutePath(), workspaceFile.getAbsolutePath());
workspaceFile = workspace.toWorkspaceFile(new URI("http://localhost:8080/files/collection/c1/bar.mov"));
expected = new File(PathSupport.concat(new String[] { workspaceRoot, "collection", "c1", "bar.mov" }));
Assert.assertEquals(expected.getAbsolutePath(), workspaceFile.getAbsolutePath());
}
@Test
public void testGetNoFilename() throws Exception {
final File expectedFile = testFolder.newFile("test.txt");
FileUtils.write(expectedFile, "asdf");
expectedFile.deleteOnExit();
WorkingFileRepository repo = EasyMock.createNiceMock(WorkingFileRepository.class);
EasyMock.expect(repo.getBaseUri()).andReturn(new URI("http://localhost:8080/files")).anyTimes();
EasyMock.replay(repo);
workspace.setRepository(repo);
RequestRunner<Either<String, Option<File>>> requestRunner = new TrustedHttpClient.RequestRunner<Either<String, Option<File>>>() {
@Override
public Either<Exception, Either<String, Option<File>>> run(Function<HttpResponse, Either<String, Option<File>>> f) {
Either<String, Option<File>> right = Either.right(Option.some(expectedFile));
return Either.right(right);
}
};
TrustedHttpClient trustedHttpClient = EasyMock.createNiceMock(TrustedHttpClient.class);
EasyMock.expect(trustedHttpClient.<Either<String, Option<File>>> runner(EasyMock.anyObject(HttpUriRequest.class)))
.andReturn(requestRunner).anyTimes();
EasyMock.replay(trustedHttpClient);
workspace.setTrustedHttpClient(trustedHttpClient);
File resultingFile = workspace.get(URI.create("http://foo.com/myaccount/videos/"));
Assert.assertEquals(expectedFile, resultingFile);
}
@Test
public void testCleanup() throws Exception {
workspace.cleanup(-1);
Assert.assertEquals(0L, workspace.getUsedSpace().get().longValue());
File file = new File(PathSupport.concat(new String[] { workspaceRoot, "test", "c1", "bar.mov" }));
FileUtils.write(file, "asdf");
file.deleteOnExit();
Assert.assertEquals(4L, workspace.getUsedSpace().get().longValue());
workspace.cleanup(0);
Assert.assertEquals(0L, workspace.getUsedSpace().get().longValue());
FileUtils.write(file, "asdf");
Assert.assertEquals(4L, workspace.getUsedSpace().get().longValue());
workspace.cleanup(100);
Assert.assertEquals(4L, workspace.getUsedSpace().get().longValue());
Prelude.sleep(1100L);
workspace.cleanup(1);
Assert.assertEquals(0L, workspace.getUsedSpace().get().longValue());
}
}