/**
* Copyright (c) Codice Foundation
* <p>
* This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser
* General Public License as published by the Free Software Foundation, either version 3 of the
* License, or any later version.
* <p>
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details. A copy of the GNU Lesser General Public License
* is distributed along with this program and can be found at
* <http://www.gnu.org/licenses/lgpl.html>.
*/
package ddf.catalog.resource.impl;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import org.apache.cxf.jaxrs.client.WebClient;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.MethodRule;
import org.junit.rules.TestWatchman;
import org.junit.runners.model.FrameworkMethod;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.ImmutableSet;
import com.google.common.net.HttpHeaders;
import ddf.catalog.operation.ResourceResponse;
import ddf.catalog.resource.Resource;
import ddf.catalog.resource.ResourceNotFoundException;
import ddf.mime.MimeTypeMapper;
import ddf.mime.MimeTypeResolver;
import ddf.mime.custom.CustomMimeTypeResolver;
import ddf.mime.mapper.MimeTypeMapperImpl;
import ddf.mime.tika.TikaMimeTypeResolver;
public class ResourceReaderTest {
private static final Logger LOGGER = LoggerFactory.getLogger(ResourceReaderTest.class);
private static final String TEST_PATH = "/src/test/resources/data/";
private static final String DEFAULT_MIME_TYPE = "application/octet-stream";
private static final String JPEG_MIME_TYPE = "image/jpeg";
private static final String VIDEO_MIME_TYPE = "video/mpeg";
private static final String MP4_MIME_TYPE = "video/mp4";
private static final String CUSTOM_MIME_TYPE = "image/xyz";
private static final String CUSTOM_FILE_EXTENSION = "xyz";
private static final String JPEG_FILE_NAME_1 = "flower.jpg";
private static final String MPEG_FILE_NAME_1 = "test.mpeg";
private static final String MP4_FILE_NAME_1 = "sample.mp4";
private static final String PPT_FILE_NAME_1 = "MissionPlan.ppt";
private static final String PPTX_FILE_NAME_1 = "MissionPlan.pptx";
private static final String HTTP_SCHEME = "http";
private static final String HTTP_SCHEME_PLUS_SEP = "http://";
private static final String FILE_SCHEME_PLUS_SEP = "file:///";
private static final String ABSOLUTE_PATH = new File(".").getAbsolutePath();
private static final String INVALID_PATH = "/my/invalid/path/";
private static final String ROOT_PATH = "/";
private static final String HOST = "127.0.0.1";
private static final String BAD_FILE_NAME =
"mydata?uri=63f30ff4dc85436ea507fceeb1396940_blahblahblah&this=that";
private static final String BYTES_TO_SKIP = "BytesToSkip";
@Rule
public MethodRule watchman = new TestWatchman() {
public void starting(FrameworkMethod method) {
LOGGER.debug("*************************** STARTING: {} **************************\n"
+ method.getName());
}
public void finished(FrameworkMethod method) {
LOGGER.debug("*************************** END: {} **************************\n"
+ method.getName());
}
};
private MimeTypeMapper mimeTypeMapper;
private CustomMimeTypeResolver customResolver;
private WebClient mockWebClient = mock(WebClient.class);
private static InputStream getBinaryData() {
byte[] sampleBytes = {65, 66, 67, 68, 69};
return new ByteArrayInputStream(sampleBytes);
}
private static InputStream getBinaryDataWithOffset(int offset) throws IOException {
byte[] sampleBytes = {65, 66, 67, 68, 69};
InputStream is = new ByteArrayInputStream(sampleBytes);
is.skip(offset);
return is;
}
@Before
public void setUp() {
MimeTypeResolver tikaResolver = new TikaMimeTypeResolver();
this.customResolver = new CustomMimeTypeResolver();
List<MimeTypeResolver> resolvers = new ArrayList<MimeTypeResolver>();
resolvers.add(tikaResolver);
resolvers.add(this.customResolver);
this.mimeTypeMapper = new MimeTypeMapperImpl(resolvers);
}
@Test
public void testURLResourceReaderBadQualifier() {
URLResourceReader resourceReader = new TestURLResourceReader(mimeTypeMapper);
resourceReader.setRootResourceDirectories(ImmutableSet.of(ABSOLUTE_PATH + TEST_PATH));
String filePath = TEST_PATH + MPEG_FILE_NAME_1;
HashMap<String, Serializable> arguments = new HashMap<String, Serializable>();
try {
LOGGER.info("Getting resource: {}", filePath);
URI uri = new URI(FILE_SCHEME_PLUS_SEP + filePath);
resourceReader.retrieveResource(uri, arguments);
} catch (IOException e) {
LOGGER.info("Successfully caught expected IOException");
fail();
} catch (ResourceNotFoundException e) {
LOGGER.info("Caught unexpected ResourceNotFoundException");
assert (true);
} catch (URISyntaxException e) {
LOGGER.info("Caught unexpected URISyntaxException");
fail();
}
}
@Test
public void testReadJPGFile() throws Exception {
String filePath = ABSOLUTE_PATH + TEST_PATH + JPEG_FILE_NAME_1;
verifyFile(filePath,
JPEG_FILE_NAME_1,
JPEG_MIME_TYPE,
ABSOLUTE_PATH + TEST_PATH,
ABSOLUTE_PATH + TEST_PATH + "pdf");
}
@Test
public void testReadMPEGFile() throws Exception {
String filePath = ABSOLUTE_PATH + TEST_PATH + MPEG_FILE_NAME_1;
verifyFile(filePath,
MPEG_FILE_NAME_1,
VIDEO_MIME_TYPE,
ABSOLUTE_PATH + TEST_PATH,
ABSOLUTE_PATH + TEST_PATH + "pdf");
}
@Test
public void testReadMP4File() throws Exception {
String filePath = ABSOLUTE_PATH + TEST_PATH + MP4_FILE_NAME_1;
verifyFile(filePath,
MP4_FILE_NAME_1,
MP4_MIME_TYPE,
ABSOLUTE_PATH + TEST_PATH,
ABSOLUTE_PATH + TEST_PATH + "pdf");
}
@Test
public void testReadPPTFile() throws Exception {
String filePath = ABSOLUTE_PATH + TEST_PATH + PPT_FILE_NAME_1;
verifyFile(filePath,
PPT_FILE_NAME_1,
"application/vnd.ms-powerpoint",
ABSOLUTE_PATH + TEST_PATH,
ABSOLUTE_PATH + TEST_PATH + "pdf");
}
@Test
public void testReadPPTXFile() throws Exception {
String filePath = ABSOLUTE_PATH + TEST_PATH + PPTX_FILE_NAME_1;
verifyFile(filePath,
PPTX_FILE_NAME_1,
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
ABSOLUTE_PATH + TEST_PATH,
ABSOLUTE_PATH + TEST_PATH + "pdf");
}
@Test
public void testReadFileWithUnknownExtension() throws Exception {
String filePath = ABSOLUTE_PATH + TEST_PATH + "UnknownExtension.hugh";
verifyFile(filePath,
"UnknownExtension.hugh",
DEFAULT_MIME_TYPE,
ABSOLUTE_PATH + TEST_PATH,
ABSOLUTE_PATH + TEST_PATH + "pdf");
}
@Test
public void testReadFileWithNoExtension() throws Exception {
String filePath = ABSOLUTE_PATH + TEST_PATH + "JpegWithoutExtension";
verifyFile(filePath,
"JpegWithoutExtension",
JPEG_MIME_TYPE,
ABSOLUTE_PATH + TEST_PATH,
ABSOLUTE_PATH + TEST_PATH + "pdf");
}
@Test
public void testReadFileWithCustomExtension() throws Exception {
// Add custom file extension to mime type mapping to custom mime type
// resolver
this.customResolver.setCustomMimeTypes(new String[] {
CUSTOM_FILE_EXTENSION + "=" + CUSTOM_MIME_TYPE});
String filePath = ABSOLUTE_PATH + TEST_PATH + "CustomExtension.xyz";
verifyFile(filePath,
"CustomExtension.xyz",
CUSTOM_MIME_TYPE,
ABSOLUTE_PATH + TEST_PATH,
ABSOLUTE_PATH + TEST_PATH + "pdf");
}
@Test
public void testJpegWithUnknownExtension() throws Exception {
String filePath = ABSOLUTE_PATH + TEST_PATH + "JpegWithUnknownExtension.hugh";
verifyFile(filePath,
"JpegWithUnknownExtension.hugh",
JPEG_MIME_TYPE,
ABSOLUTE_PATH + TEST_PATH,
ABSOLUTE_PATH + TEST_PATH + "pdf");
}
@Test
public void testJpegWithCustomExtension() throws Exception {
// Add custom file extension to mime type mapping to custom mime type
// resolver
this.customResolver.setCustomMimeTypes(new String[] {
CUSTOM_FILE_EXTENSION + "=" + CUSTOM_MIME_TYPE});
String filePath = ABSOLUTE_PATH + TEST_PATH + "JpegWithCustomExtension.xyz";
verifyFile(filePath,
"JpegWithCustomExtension.xyz",
CUSTOM_MIME_TYPE,
ABSOLUTE_PATH + TEST_PATH,
ABSOLUTE_PATH + TEST_PATH + "pdf");
}
@Test
public void testJpegWithOverriddenExtension() throws Exception {
// Override/redefine .jpg file extension to custom mime type mapping of
// "image/xyz"
this.customResolver.setCustomMimeTypes(new String[] {"jpg=" + CUSTOM_MIME_TYPE});
String filePath = ABSOLUTE_PATH + TEST_PATH + JPEG_FILE_NAME_1;
verifyFile(filePath,
JPEG_FILE_NAME_1,
CUSTOM_MIME_TYPE,
ABSOLUTE_PATH + TEST_PATH,
ABSOLUTE_PATH + TEST_PATH + "pdf");
}
@Test
public void testURLResourceIOException() throws Exception {
URLResourceReader resourceReader = new URLResourceReader(mimeTypeMapper);
String filePath = "JUMANJI!!!!";
HashMap<String, Serializable> arguments = new HashMap<String, Serializable>();
try {
LOGGER.info("Getting resource: {}", filePath);
URI uri = new URI(FILE_SCHEME_PLUS_SEP + filePath);
resourceReader.retrieveResource(uri, arguments);
} catch (IOException e) {
LOGGER.info("Successfully caught IOException");
fail();
} catch (ResourceNotFoundException e) {
LOGGER.info("Caught ResourceNotFoundException");
assert (true);
} catch (URISyntaxException e) {
LOGGER.info("Caught unexpected URISyntaxException");
fail();
}
}
@Test
public void testUrlToNonExistentFile() throws Exception {
URLResourceReader resourceReader = new URLResourceReader(mimeTypeMapper);
String filePath = ABSOLUTE_PATH + TEST_PATH + "NonExistentFile.jpg";
HashMap<String, Serializable> arguments = new HashMap<String, Serializable>();
try {
LOGGER.info("Getting resource: {}", filePath);
File file = new File(filePath);
URI uri = file.toURI();
resourceReader.retrieveResource(uri, arguments);
} catch (IOException e) {
LOGGER.info("Successfully caught IOException");
fail();
} catch (ResourceNotFoundException e) {
LOGGER.info("Caught ResourceNotFoundException");
assert (true);
}
}
@Test
public void testHTTPReturnsFileNameWithoutPath() throws Exception {
URI uri = new URI(HTTP_SCHEME_PLUS_SEP + HOST + TEST_PATH + JPEG_FILE_NAME_1);
verifyFileFromURLResourceReader(uri, JPEG_FILE_NAME_1, JPEG_MIME_TYPE);
Path pathForUri = Paths.get(ABSOLUTE_PATH, TEST_PATH, JPEG_FILE_NAME_1);
uri = pathForUri.toUri();
verifyFileFromURLResourceReader(uri, JPEG_FILE_NAME_1, JPEG_MIME_TYPE);
}
@Test
public void testNameInContentDisposition() throws Exception {
URI uri = new URI(HTTP_SCHEME_PLUS_SEP + HOST + TEST_PATH + BAD_FILE_NAME);
Response mockResponse = mock(Response.class);
when(mockWebClient.get()).thenReturn(mockResponse);
MultivaluedMap<String, Object> map = new MultivaluedHashMap<>();
map.put(HttpHeaders.CONTENT_DISPOSITION,
Arrays.<Object>asList("inline; filename=\"" + JPEG_FILE_NAME_1 + "\""));
when(mockResponse.getHeaders()).thenReturn(map);
when(mockResponse.getStatus()).thenReturn(Response.Status.OK.getStatusCode());
when(mockResponse.getEntity()).thenReturn(getBinaryData());
ResourceResponse response = verifyFileFromURLResourceReader(uri,
JPEG_FILE_NAME_1,
JPEG_MIME_TYPE,
null);
// verify that we got the entire resource
assertEquals(5,
response.getResource()
.getByteArray().length);
}
/**
* Tests that a Partial Content response that has the same byte offset as what was requested
* returns an input stream starting at the requested byte offset.
* @throws Exception
*/
@Test
public void testServerSupportsPartialContentResponseWithCorrectOffset() throws Exception {
URI uri = new URI(HTTP_SCHEME_PLUS_SEP + HOST + TEST_PATH + BAD_FILE_NAME);
Response mockResponse = mock(Response.class);
when(mockWebClient.get()).thenReturn(mockResponse);
MultivaluedMap<String, Object> map = new MultivaluedHashMap<>();
map.put(HttpHeaders.CONTENT_DISPOSITION,
Arrays.asList("inline; filename=\"" + JPEG_FILE_NAME_1 + "\""));
map.put(HttpHeaders.CONTENT_RANGE,
Arrays.asList("Bytes 2-4/5"));
when(mockResponse.getHeaders()).thenReturn(map);
when(mockResponse.getStatus()).thenReturn(Response.Status.PARTIAL_CONTENT.getStatusCode());
when(mockResponse.getEntity()).thenReturn(getBinaryDataWithOffset(2));
String bytesToSkip = "2";
ResourceResponse response = verifyFileFromURLResourceReader(uri,
JPEG_FILE_NAME_1,
JPEG_MIME_TYPE,
bytesToSkip);
// verify that the requested bytes 3-5 were returned
assertEquals(3,
response.getResource()
.getByteArray().length);
}
/**
* Tests that a Partial Content response that has a smaller byte offset than what was requested
* still returns an input stream starting at the requested byte offset by skipping ahead in the
* input stream.
* @throws Exception
*/
@Test
public void testServerSupportsPartialContentResponseWithNotEnoughOffset() throws Exception {
URI uri = new URI(HTTP_SCHEME_PLUS_SEP + HOST + TEST_PATH + BAD_FILE_NAME);
Response mockResponse = mock(Response.class);
when(mockWebClient.get()).thenReturn(mockResponse);
MultivaluedMap<String, Object> map = new MultivaluedHashMap<>();
map.put(HttpHeaders.CONTENT_DISPOSITION,
Arrays.asList("inline; filename=\"" + JPEG_FILE_NAME_1 + "\""));
map.put(HttpHeaders.CONTENT_RANGE,
Arrays.asList("Bytes 1-4/5"));
when(mockResponse.getHeaders()).thenReturn(map);
when(mockResponse.getStatus()).thenReturn(Response.Status.PARTIAL_CONTENT.getStatusCode());
when(mockResponse.getEntity()).thenReturn(getBinaryDataWithOffset(1));
String bytesToSkip = "2";
ResourceResponse response = verifyFileFromURLResourceReader(uri,
JPEG_FILE_NAME_1,
JPEG_MIME_TYPE,
bytesToSkip);
// verify that the requested bytes 3-5 were returned
assertEquals(3,
response.getResource()
.getByteArray().length);
}
/**
* Tests that a Partial Content response that has a higher byte offset as what was requested
* throws an IOException in order to prevent data loss.
* @throws Exception
*/
@Test(expected=ResourceNotFoundException.class)
public void testServerSupportsPartialContentResponseTooMuchOffset() throws Exception {
URI uri = new URI(HTTP_SCHEME_PLUS_SEP + HOST + TEST_PATH + BAD_FILE_NAME);
Response mockResponse = mock(Response.class);
when(mockWebClient.get()).thenReturn(mockResponse);
MultivaluedMap<String, Object> map = new MultivaluedHashMap<>();
map.put(HttpHeaders.CONTENT_DISPOSITION,
Arrays.asList("inline; filename=\"" + JPEG_FILE_NAME_1 + "\""));
map.put(HttpHeaders.CONTENT_RANGE,
Arrays.asList("Bytes 3-4/5"));
when(mockResponse.getHeaders()).thenReturn(map);
when(mockResponse.getStatus()).thenReturn(Response.Status.PARTIAL_CONTENT.getStatusCode());
when(mockResponse.getEntity()).thenReturn(getBinaryDataWithOffset(3));
String bytesToSkip = "2";
// this should throw an IOException since more bytes were skipped than requested
verifyFileFromURLResourceReader(uri, JPEG_FILE_NAME_1, JPEG_MIME_TYPE, bytesToSkip);
}
/**
* Tests that if the server does not support range-header requests and responds with the entire
* product's contents (no Content-Range header and a 200 response), an input is still returned
* with the requested byte offset.
* @throws Exception
*/
@Test
public void testServerDoesNotSupportPartialContent() throws Exception {
URI uri = new URI(HTTP_SCHEME_PLUS_SEP + HOST + TEST_PATH + BAD_FILE_NAME);
Response mockResponse = mock(Response.class);
when(mockWebClient.get()).thenReturn(mockResponse);
MultivaluedMap<String, Object> map = new MultivaluedHashMap<>();
map.put(HttpHeaders.CONTENT_DISPOSITION,
Arrays.asList("inline; filename=\"" + JPEG_FILE_NAME_1 + "\""));
when(mockResponse.getHeaders()).thenReturn(map);
when(mockResponse.getStatus()).thenReturn(Response.Status.OK.getStatusCode());
when(mockResponse.getEntity()).thenReturn(getBinaryData());
String bytesToSkip = "2";
ResourceResponse response = verifyFileFromURLResourceReader(uri,
JPEG_FILE_NAME_1,
JPEG_MIME_TYPE,
bytesToSkip);
// verify that the requested bytes 3-5 were returned
assertEquals(3,
response.getResource()
.getByteArray().length);
}
@Test
public void testUnquotedNameInContentDisposition() throws Exception {
URI uri = new URI(HTTP_SCHEME_PLUS_SEP + HOST + TEST_PATH + BAD_FILE_NAME);
Response mockResponse = mock(Response.class);
when(mockWebClient.get()).thenReturn(mockResponse);
MultivaluedMap<String, Object> map = new MultivaluedHashMap<>();
map.put(HttpHeaders.CONTENT_DISPOSITION,
Arrays.<Object>asList("inline; filename=" + JPEG_FILE_NAME_1));
when(mockResponse.getHeaders()).thenReturn(map);
when(mockResponse.getStatus()).thenReturn(Response.Status.OK.getStatusCode());
when(mockResponse.getEntity()).thenReturn(getBinaryData());
verifyFileFromURLResourceReader(uri, JPEG_FILE_NAME_1, JPEG_MIME_TYPE, null);
}
@Test
public void testUnquotedNameEndingSemicolonInContentDisposition() throws Exception {
URI uri = new URI(HTTP_SCHEME_PLUS_SEP + HOST + TEST_PATH + BAD_FILE_NAME);
Response mockResponse = mock(Response.class);
when(mockWebClient.get()).thenReturn(mockResponse);
MultivaluedMap<String, Object> map = new MultivaluedHashMap<>();
map.put(HttpHeaders.CONTENT_DISPOSITION,
Arrays.<Object>asList("inline;filename=" + JPEG_FILE_NAME_1 + ";"));
when(mockResponse.getHeaders()).thenReturn(map);
when(mockResponse.getStatus()).thenReturn(Response.Status.OK.getStatusCode());
when(mockResponse.getEntity()).thenReturn(getBinaryData());
verifyFileFromURLResourceReader(uri, JPEG_FILE_NAME_1, JPEG_MIME_TYPE, null);
}
@Test
public void testURLResourceReaderQualifierSet() throws Exception {
URLResourceReader resourceReader = new URLResourceReader(mimeTypeMapper);
Set<String> qualifiers = resourceReader.getSupportedSchemes();
assert (qualifiers != null);
assert (qualifiers.contains(HTTP_SCHEME));
assert (qualifiers.size() == 3);
}
@Test(expected = ResourceNotFoundException.class)
public void testReadFileInvalidResourcePath() throws Exception {
String invalidFilePath = INVALID_PATH + JPEG_FILE_NAME_1;
verifyFile(invalidFilePath,
JPEG_FILE_NAME_1,
JPEG_MIME_TYPE,
ABSOLUTE_PATH + TEST_PATH,
ABSOLUTE_PATH + TEST_PATH + "pdf");
}
@Test(expected = ResourceNotFoundException.class)
public void testReadFileInvalidResourcePathWithBackReferences() throws Exception {
String invalidFilePath = ABSOLUTE_PATH + TEST_PATH + "../../../../../" + JPEG_FILE_NAME_1;
verifyFile(invalidFilePath,
JPEG_FILE_NAME_1,
JPEG_MIME_TYPE,
ABSOLUTE_PATH + TEST_PATH,
ABSOLUTE_PATH + TEST_PATH + "pdf");
}
@Test
public void testReadFileResourceDirectoryIsRoot() throws Exception {
String filePath = ABSOLUTE_PATH + TEST_PATH + JPEG_FILE_NAME_1;
verifyFile(filePath, JPEG_FILE_NAME_1, JPEG_MIME_TYPE, ROOT_PATH);
}
@Test
public void testRemoveARootResourceDirectory() throws Exception {
// Setup (2 paths)
URLResourceReader resourceReader = new URLResourceReader(mimeTypeMapper);
resourceReader.setRootResourceDirectories(ImmutableSet.of(ABSOLUTE_PATH + TEST_PATH,
ABSOLUTE_PATH + TEST_PATH + "pdf"));
// Perform Test (remove a path). NOTE: the complete set of configured root resource
// directories
// is passed in (not just the path to remove). In this case, ABSOLUTE_PATH + TEST_PATH +
// "pdf" is removed.
resourceReader.setRootResourceDirectories(ImmutableSet.of(ABSOLUTE_PATH + TEST_PATH));
// Verify
Set<String> rootResourceDirectories = resourceReader.getRootResourceDirectories();
assertThat(rootResourceDirectories.size(), is(1));
assertThat(rootResourceDirectories, hasItems(Paths.get(ABSOLUTE_PATH + TEST_PATH)
.normalize()
.toString()));
}
@Test
public void testAddARootResourceDirectory() throws Exception {
// Setup (2 paths)
URLResourceReader resourceReader = new URLResourceReader(mimeTypeMapper);
resourceReader.setRootResourceDirectories(ImmutableSet.of(ABSOLUTE_PATH + TEST_PATH,
ABSOLUTE_PATH + TEST_PATH + "pdf"));
// Perform Test (add a path). NOTE: the complete set of configured root resource directories
// is passed in (not just the path to add). In this case, ABSOLUTE_PATH + TEST_PATH + "doc"
// is added.
resourceReader.setRootResourceDirectories(ImmutableSet.of(ABSOLUTE_PATH + TEST_PATH,
ABSOLUTE_PATH + TEST_PATH + "pdf",
ABSOLUTE_PATH + TEST_PATH + "doc"));
// Verify
Set<String> rootResourceDirectories = resourceReader.getRootResourceDirectories();
assertThat(rootResourceDirectories.size(), is(3));
assertThat(rootResourceDirectories, hasItems(Paths.get(ABSOLUTE_PATH + TEST_PATH)
.normalize()
.toString(), Paths.get(ABSOLUTE_PATH + TEST_PATH + "pdf")
.normalize()
.toString(), Paths.get(ABSOLUTE_PATH + TEST_PATH + "doc")
.normalize()
.toString()));
}
/**
* Verify the URLResourceReader's Root Resource Directories gets set to an empty Set when null
* is passed into setRootResourceDirectories.
*/
@Test
public void testSetRootResourceDirectoriesNullInput() throws Exception {
// Setup (2 paths)
URLResourceReader resourceReader = new URLResourceReader(mimeTypeMapper);
resourceReader.setRootResourceDirectories(ImmutableSet.of(ABSOLUTE_PATH + TEST_PATH,
ABSOLUTE_PATH + TEST_PATH + "pdf"));
// Perform Test
resourceReader.setRootResourceDirectories(null);
// Verify
Set<String> rootResourceDirectories = resourceReader.getRootResourceDirectories();
assertThat(rootResourceDirectories.size(), is(0));
}
/**
* Verify the URLResourceReader's Root Resource Directories gets set to an empty Set when an
* empty Set is passed into setRootResourceDirectories.
*/
@Test
public void testSetRootResourceDirectoriesEmptySetInput() throws Exception {
// Setup (2 paths)
URLResourceReader resourceReader = new URLResourceReader(mimeTypeMapper);
resourceReader.setRootResourceDirectories(ImmutableSet.of(ABSOLUTE_PATH + TEST_PATH,
ABSOLUTE_PATH + TEST_PATH + "pdf"));
// Perform Test
resourceReader.setRootResourceDirectories(new HashSet<String>());
// Verify
Set<String> rootResourceDirectories = resourceReader.getRootResourceDirectories();
assertThat(rootResourceDirectories.size(), is(0));
}
@Test
public void testSetRootResourceDirectoriesInvalidPath() throws Exception {
// Setup (1 valid paths, 1 invalid path)
String invalidPath = "\0";
URLResourceReader resourceReader = new URLResourceReader(mimeTypeMapper);
// Perform Test
resourceReader.setRootResourceDirectories(ImmutableSet.of(ABSOLUTE_PATH + TEST_PATH,
ABSOLUTE_PATH + TEST_PATH + invalidPath));
// Verify
Set<String> rootResourceDirectories = resourceReader.getRootResourceDirectories();
assertThat(rootResourceDirectories.size(), is(1));
}
@Test
public void testSetRedirect() throws Exception {
URLResourceReader resourceReader = new URLResourceReader(mimeTypeMapper);
WebClient client = resourceReader.getWebClient(HTTP_SCHEME_PLUS_SEP + HOST + TEST_PATH
+ JPEG_FILE_NAME_1, new HashMap<>());
assertFalse(WebClient.getConfig(client).getHttpConduit().getClient().isAutoRedirect());
resourceReader.setFollowRedirects(true);
client = resourceReader.getWebClient(HTTP_SCHEME_PLUS_SEP + HOST + TEST_PATH
+ JPEG_FILE_NAME_1, new HashMap<>());
assertTrue(WebClient.getConfig(client).getHttpConduit().getClient()
.isAutoRedirect());
resourceReader.setFollowRedirects(false);
client = resourceReader.getWebClient(HTTP_SCHEME_PLUS_SEP + HOST + TEST_PATH
+ JPEG_FILE_NAME_1, new HashMap<>());
assertFalse(WebClient.getConfig(client).getHttpConduit().getClient().isAutoRedirect());
}
private void verifyFile(String filePath, String filename, String expectedMimeType,
String... rootResourceDirectories) throws Exception {
URLResourceReader resourceReader = new URLResourceReader(mimeTypeMapper);
resourceReader.setRootResourceDirectories(new HashSet<String>(Arrays.asList(
rootResourceDirectories)));
HashMap<String, Serializable> arguments = new HashMap<String, Serializable>();
LOGGER.info("Getting resource: {}", filePath);
// Test using the URL ResourceReader
File file = new File(filePath);
URI uri = file.toURI();
LOGGER.info("URI: {}", uri.toString());
ResourceResponse resourceResponse = resourceReader.retrieveResource(uri, arguments);
Resource resource = resourceResponse.getResource();
assert (resource != null);
LOGGER.info("MimeType: {}", resource.getMimeType());
LOGGER.info("Got resource: {}", resource.getName());
String name = resource.getName();
assertNotNull(name);
assertThat(name, is(filename));
assertThat(resource.getMimeType()
.toString(), containsString(expectedMimeType));
}
private void verifyFileFromURLResourceReader(URI uri, String filename, String expectedMimeType)
throws URISyntaxException, IOException, ResourceNotFoundException {
Response mockResponse = mock(Response.class);
when(mockWebClient.get()).thenReturn(mockResponse);
MultivaluedMap<String, Object> map = new MultivaluedHashMap<>();
map.put(HttpHeaders.CONTENT_DISPOSITION,
Arrays.<Object>asList("inline; filename=\"" + filename + "\""));
when(mockResponse.getHeaders()).thenReturn(map);
when(mockResponse.getStatus()).thenReturn(Response.Status.OK.getStatusCode());
when(mockResponse.getEntity()).thenReturn(getBinaryData());
verifyFileFromURLResourceReader(uri, filename, expectedMimeType, null);
}
// Create arguments, adding bytesToSkip if present, and call doVerification
private ResourceResponse verifyFileFromURLResourceReader(URI uri, String filename,
String expectedMimeType, String bytesToSkip)
throws URISyntaxException, IOException, ResourceNotFoundException {
Map<String, Serializable> arguments = new HashMap<String, Serializable>();
if (bytesToSkip != null) {
arguments.put(BYTES_TO_SKIP, bytesToSkip);
}
return doVerification(uri, filename, expectedMimeType, arguments);
}
private ResourceResponse doVerification(URI uri, String filename, String expectedMimeType,
Map<String, Serializable> arguments)
throws URISyntaxException, IOException, ResourceNotFoundException {
URLResourceReader resourceReader = new TestURLResourceReader(mimeTypeMapper);
resourceReader.setRootResourceDirectories(ImmutableSet.of(ABSOLUTE_PATH + TEST_PATH));
// Test using the URL ResourceReader
LOGGER.info("URI: {}", uri.toString());
ResourceResponse resourceResponse = resourceReader.retrieveResource(uri, arguments);
Resource resource = resourceResponse.getResource();
assert (resource != null);
LOGGER.info("MimeType: {}", resource.getMimeType());
LOGGER.info("Got resource: {}", resource.getName());
String name = resource.getName();
assertNotNull(name);
assertThat(name, is(filename));
assertTrue(resource.getMimeType()
.toString()
.contains(expectedMimeType));
return resourceResponse;
}
private class TestURLResourceReader extends URLResourceReader {
public TestURLResourceReader(MimeTypeMapper mimeTypeMapper) {
super(mimeTypeMapper);
}
@Override
protected WebClient getWebClient(String uri, Map<String, Serializable> properties) {
return mockWebClient;
}
}
}