/** * Copyright (c) Codice Foundation * * 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. * * 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 org.codice.ddf.spatial.ogc.catalog.resource.impl; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.Serializable; import java.io.StringWriter; import java.net.InetSocketAddress; import java.net.URI; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.apache.commons.io.IOUtils; 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.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; 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 TestResourceReader { private static final Logger LOGGER = LoggerFactory.getLogger(TestResourceReader.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_PLUS_SEP = "http://"; private static final String ABSOLUTE_PATH = new File(".").getAbsolutePath(); private static final int MOCK_HTTP_SERVER_PORT = 29992; private static final String MOCK_HTTP_SERVER_HOST = "localhost"; private static final String MOCK_HTTP_SERVER_PATH = "/mock/http/path"; private static final int MOCK_HTTP_SERVER_STOP_DELAY = 1; private static final String MOCK_HTTP_SERVER_ENCODING = "UTF-8"; private static final int HTTP_SUCCESS_CODE = 200; @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 static String getStringFromInputStream(InputStream inputStream) { BufferedReader bufferedReader = null; StringBuilder stringBuilder = new StringBuilder(); String line; try { bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); while ((line = bufferedReader.readLine()) != null) { stringBuilder.append(line + "\n"); } } catch (IOException e) { LOGGER.error("IOException on reading input stream: " + e.getMessage()); fail(e.getMessage()); } finally { if (bufferedReader != null) { try { bufferedReader.close(); } catch (IOException e) { LOGGER.error("Error closing bufferedReader in test"); } } } return stringBuilder.toString(); } @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 testReadJPGFile() { String filePath = ABSOLUTE_PATH + TEST_PATH + JPEG_FILE_NAME_1; verifyFile(filePath, JPEG_FILE_NAME_1, JPEG_MIME_TYPE); } @Test public void testReadMPEGFile() { String filePath = ABSOLUTE_PATH + TEST_PATH + MPEG_FILE_NAME_1; verifyFile(filePath, MPEG_FILE_NAME_1, VIDEO_MIME_TYPE); } @Test public void testReadMP4File() { String filePath = ABSOLUTE_PATH + TEST_PATH + MP4_FILE_NAME_1; verifyFile(filePath, MP4_FILE_NAME_1, MP4_MIME_TYPE); } @Test public void testReadPPTFile() { String filePath = ABSOLUTE_PATH + TEST_PATH + PPT_FILE_NAME_1; verifyFile(filePath, PPT_FILE_NAME_1, "application/vnd.ms-powerpoint"); } @Test public void testReadPPTXFile() { String filePath = ABSOLUTE_PATH + TEST_PATH + PPTX_FILE_NAME_1; verifyFile(filePath, PPTX_FILE_NAME_1, "application/vnd.openxmlformats-officedocument.presentationml.presentation"); } @Test public void testReadFileWithUnknownExtension() { String filePath = ABSOLUTE_PATH + TEST_PATH + "UnknownExtension.hugh"; verifyFile(filePath, "UnknownExtension.hugh", DEFAULT_MIME_TYPE); } @Test public void testReadFileWithNoExtension() { String filePath = ABSOLUTE_PATH + TEST_PATH + "JpegWithoutExtension"; verifyFile(filePath, "JpegWithoutExtension", JPEG_MIME_TYPE); } @Test public void testReadFileWithCustomExtension() { // 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); } @Test public void testJpegWithUnknownExtension() { String filePath = ABSOLUTE_PATH + TEST_PATH + "JpegWithUnknownExtension.hugh"; verifyFile(filePath, "JpegWithUnknownExtension.hugh", JPEG_MIME_TYPE); } @Test public void testJpegWithCustomExtension() { // 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); } @Test public void testJpegWithOverriddenExtension() { // 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); } @Test public void testOgcUrlResourceReaderHtmlContent() throws Exception { OgcUrlResourceReader resourceReader = new OgcUrlResourceReader(mimeTypeMapper); HttpServer mockHttpServer = HttpServer .create(new InetSocketAddress(MOCK_HTTP_SERVER_PORT), 0); mockHttpServer.createContext(MOCK_HTTP_SERVER_PATH, new MockHttpServerSuccessResponse(MOCK_HTTP_SERVER_HOST, MOCK_HTTP_SERVER_PORT)); mockHttpServer.setExecutor(null); mockHttpServer.start(); String httpUriStr = HTTP_SCHEME_PLUS_SEP + MOCK_HTTP_SERVER_HOST + ":" + MOCK_HTTP_SERVER_PORT + MOCK_HTTP_SERVER_PATH; URI uri = new URI(httpUriStr); HashMap<String, Serializable> arguments = new HashMap<String, Serializable>(); ResourceResponse resourceResponse = resourceReader.retrieveResource(uri, arguments); StringWriter writer = new StringWriter(); IOUtils.copy(resourceResponse.getResource().getInputStream(), writer, MOCK_HTTP_SERVER_ENCODING); String responseString = writer.toString(); LOGGER.info("Response " + responseString); assertEquals(responseString, "<html><script type=\"text/javascript\">window.location.replace(\"" + httpUriStr + "\");</script></html>"); mockHttpServer.stop(MOCK_HTTP_SERVER_STOP_DELAY); } private void verifyFile(String filePath, String filename, String expectedMimeType) { OgcUrlResourceReader resourceReader = new OgcUrlResourceReader(mimeTypeMapper); HashMap<String, Serializable> arguments = new HashMap<>(); try { 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); assertTrue(name.equals(filename)); assertTrue(resource.getMimeType().toString().contains(expectedMimeType)); } catch (IOException e) { LOGGER.info("Caught unexpected IOException"); fail(); } catch (ResourceNotFoundException e) { LOGGER.info("Caught unexpected ResourceNotFoundException"); fail(); } } static class MockHttpServerSuccessResponse implements HttpHandler { private String mockHost; private int mockPort; public MockHttpServerSuccessResponse(String mockHost, int mockPort) { this.mockHost = mockHost; this.mockPort = mockPort; } @Override public void handle(HttpExchange httpExchange) throws IOException { String response = "<!DOCTYPE HTML><html><head><title>dummy</title></head><body>dummy</body></html>"; InputStream inputStream = httpExchange.getRequestBody(); LOGGER.info("request was '{}'", getStringFromInputStream(inputStream)); //TODO assert httpExchange.sendResponseHeaders(HTTP_SUCCESS_CODE, response.length()); OutputStream outputStream = httpExchange.getResponseBody(); outputStream.write(response.getBytes()); outputStream.close(); } } }