/** * 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 org.codice.ddf.endpoints.rest; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasItems; import static org.hamcrest.Matchers.notNullValue; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Matchers.isA; import static org.mockito.Matchers.isNull; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.activation.MimeType; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriInfo; import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.cxf.jaxrs.ext.multipart.Attachment; import org.apache.cxf.jaxrs.ext.multipart.ContentDisposition; import org.apache.cxf.jaxrs.ext.multipart.MultipartBody; import org.apache.tika.io.IOUtils; import org.junit.BeforeClass; import org.junit.Test; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.osgi.framework.BundleContext; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ddf.catalog.CatalogFramework; import ddf.catalog.content.operation.CreateStorageRequest; import ddf.catalog.data.BinaryContent; import ddf.catalog.data.ContentType; import ddf.catalog.data.Metacard; import ddf.catalog.data.Result; import ddf.catalog.data.impl.BasicTypes; import ddf.catalog.data.impl.ContentTypeImpl; import ddf.catalog.data.impl.MetacardImpl; import ddf.catalog.federation.FederationException; import ddf.catalog.federation.FederationStrategy; import ddf.catalog.filter.FilterBuilder; import ddf.catalog.filter.proxy.builder.GeotoolsFilterBuilder; import ddf.catalog.operation.CreateRequest; import ddf.catalog.operation.QueryRequest; import ddf.catalog.operation.QueryResponse; import ddf.catalog.operation.SourceInfoResponse; import ddf.catalog.operation.impl.CreateResponseImpl; import ddf.catalog.operation.impl.SourceInfoRequestEnterprise; import ddf.catalog.operation.impl.SourceInfoResponseImpl; import ddf.catalog.resource.Resource; import ddf.catalog.resource.ResourceNotSupportedException; import ddf.catalog.source.IngestException; import ddf.catalog.source.SourceDescriptor; import ddf.catalog.source.SourceUnavailableException; import ddf.catalog.source.UnsupportedQueryException; import ddf.catalog.source.impl.SourceDescriptorImpl; import ddf.catalog.transform.CatalogTransformerException; import ddf.catalog.transform.InputTransformer; import ddf.mime.MimeTypeMapper; import ddf.mime.MimeTypeResolutionException; import ddf.mime.MimeTypeToTransformerMapper; import ddf.mime.tika.TikaMimeTypeResolver; import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; import net.minidev.json.parser.JSONParser; /** * Tests methods of the {@link RESTEndpoint} */ public class TestRestEndpoint { private static final int OK = 200; private static final int NO_CONTENT = 204; private static final int INTERNAL_SERVER_ERROR = 500; private static final int BAD_REQUEST = 400; private static final String SAMPLE_ID = "12345678900987654321abcdeffedcba"; private static final String ENDPOINT_ADDRESS = "http://localhost:8181/services/catalog"; private static final Logger LOGGER = LoggerFactory.getLogger(TestRestEndpoint.class); private static final String LOCAL_RETRIEVE_ADDRESS = "http://localhost:8181/services/catalog"; private static final String FED_RETRIEVE_ADDRESS = "http://localhost:8181/services/catalog/sources/test/abc123456def"; private static final String GET_SITENAME = "test"; private static final String GET_ID = "abc123456def"; private static final String GET_STREAM = "Test string for inputstream."; private static final String GET_OUTPUT_TYPE = "UTF-8"; private static final String GET_MIME_TYPE = "text/xml"; private static final String GET_KML_MIME_TYPE = "application/vnd.google-earth.kml+xml"; private static final String GET_FILENAME = "example.xml"; private static final String GET_TYPE_OUTPUT = "{Content-Type=[text/xml], Accept-Ranges=[bytes], " + "Content-Disposition=[inline; filename=\"" + GET_FILENAME + "\"]}"; private static final String GET_KML_TYPE_OUTPUT = "{Content-Type=[application/vnd.google-earth.kml+xml], " + "Accept-Ranges=[bytes], Content-Disposition=[inline; filename=\"" + GET_ID + ".kml" + "\"]}"; private static final String HEADER_RANGE = "Range"; private static final String HEADER_ACCEPT_RANGES = "Accept-Ranges"; private static final String ACCEPT_RANGES_VALUE = "bytes"; private static final String HEADER_CONTENT_DISPOSITION = "Content-Disposition"; private static final String CONTENT_DISPOSITION_VALUE = "inline; filename=\"" + GET_FILENAME + "\""; @BeforeClass public static void initialize() throws Exception { } @Test(expected = ServerErrorException.class) public void testAddDocumentNullMessage() { CatalogFramework framework = mock(CatalogFramework.class); RESTEndpoint rest = new RESTEndpoint(framework); HttpHeaders headers = mock(HttpHeaders.class); rest.addDocument(headers, mock(UriInfo.class), mock(HttpServletRequest.class), mock(MultipartBody.class), null, null); } @Test() public void testAddDocumentFrameworkIngestException() throws IngestException, SourceUnavailableException, URISyntaxException { assertExceptionThrown(IngestException.class); } @Test() public void testAddDocumentFrameworkSourceUnavailableException() throws IngestException, SourceUnavailableException, URISyntaxException { assertExceptionThrown(SourceUnavailableException.class); } @Test() public void testAddDocumentPositiveCase() throws IOException, CatalogTransformerException, IngestException, SourceUnavailableException, URISyntaxException { CatalogFramework framework = givenCatalogFramework(SAMPLE_ID); HttpHeaders headers = createHeaders(Arrays.asList(MediaType.APPLICATION_JSON)); RESTEndpoint rest = new RESTEndpoint(framework); addMatchingService(rest, Arrays.asList(getSimpleTransformer())); UriInfo info = givenUriInfo(SAMPLE_ID); Response response = rest.addDocument(headers, info, mock(HttpServletRequest.class), mock(MultipartBody.class), null, new ByteArrayInputStream("".getBytes())); LOGGER.debug(ToStringBuilder.reflectionToString(response)); assertThat(response.getStatus(), equalTo(201)); assertThat(response.getMetadata(), notNullValue()); assertThat(response.getMetadata() .get(Metacard.ID) .get(0) .toString(), equalTo(SAMPLE_ID)); } @Test() public void testAddDocumentWithMetadataPositiveCase() throws IOException, CatalogTransformerException, IngestException, SourceUnavailableException, URISyntaxException, InvalidSyntaxException, MimeTypeResolutionException { CatalogFramework framework = givenCatalogFramework(SAMPLE_ID); HttpHeaders headers = createHeaders(Arrays.asList(MediaType.APPLICATION_JSON)); BundleContext bundleContext = mock(BundleContext.class); Collection<ServiceReference<InputTransformer>> serviceReferences = new ArrayList<>(); ServiceReference serviceReference = mock(ServiceReference.class); InputTransformer inputTransformer = mock(InputTransformer.class); when(inputTransformer.transform(any())).thenReturn(new MetacardImpl()); when(bundleContext.getService(serviceReference)).thenReturn(inputTransformer); serviceReferences.add(serviceReference); when(bundleContext.getServiceReferences(InputTransformer.class, "(id=xml)")).thenReturn(serviceReferences); RESTEndpoint rest = new RESTEndpoint(framework) { @Override BundleContext getBundleContext() { return bundleContext; } }; rest.setMetacardTypes(Collections.singletonList(BasicTypes.BASIC_METACARD)); MimeTypeMapper mimeTypeMapper = mock(MimeTypeMapper.class); when(mimeTypeMapper.getMimeTypeForFileExtension("txt")).thenReturn("text/plain"); when(mimeTypeMapper.getMimeTypeForFileExtension("xml")).thenReturn("text/xml"); rest.setMimeTypeMapper(mimeTypeMapper); addMatchingService(rest, Arrays.asList(getSimpleTransformer())); UriInfo info = givenUriInfo(SAMPLE_ID); List<Attachment> attachments = new ArrayList<>(); ContentDisposition contentDisposition = new ContentDisposition( "form-data; name=parse.resource; filename=C:\\DDF\\metacard.txt"); Attachment attachment = new Attachment("parse.resource", new ByteArrayInputStream("Some Text".getBytes()), contentDisposition); attachments.add(attachment); ContentDisposition contentDisposition1 = new ContentDisposition( "form-data; name=parse.metadata; filename=C:\\DDF\\metacard.xml"); Attachment attachment1 = new Attachment("parse.metadata", new ByteArrayInputStream("Some Text Again".getBytes()), contentDisposition1); attachments.add(attachment1); ContentDisposition contentDisposition2 = new ContentDisposition( "form-data; name=metadata; filename=C:\\DDF\\metacard.xml"); Attachment attachment2 = new Attachment("metadata", new ByteArrayInputStream("<meta>beta</meta>".getBytes()), contentDisposition2); attachments.add(attachment2); MultipartBody multipartBody = new MultipartBody(attachments); Response response = rest.addDocument(headers, info, mock(HttpServletRequest.class), multipartBody, null, new ByteArrayInputStream("".getBytes())); LOGGER.debug(ToStringBuilder.reflectionToString(response)); assertThat(response.getStatus(), equalTo(201)); assertThat(response.getMetadata(), notNullValue()); assertThat(response.getMetadata() .get(Metacard.ID) .get(0) .toString(), equalTo(SAMPLE_ID)); } @Test public void testParseAttachments() throws IOException, CatalogTransformerException, SourceUnavailableException, IngestException, InvalidSyntaxException, MimeTypeResolutionException, URISyntaxException { CatalogFramework framework = givenCatalogFramework(SAMPLE_ID); BundleContext bundleContext = mock(BundleContext.class); Collection<ServiceReference<InputTransformer>> serviceReferences = new ArrayList<>(); ServiceReference serviceReference = mock(ServiceReference.class); InputTransformer inputTransformer = mock(InputTransformer.class); MetacardImpl metacard = new MetacardImpl(); metacard.setMetadata("Some Text Again"); when(inputTransformer.transform(any())).thenReturn(metacard); when(bundleContext.getService(serviceReference)).thenReturn(inputTransformer); serviceReferences.add(serviceReference); when(bundleContext.getServiceReferences(InputTransformer.class, "(id=xml)")).thenReturn(serviceReferences); RESTEndpoint rest = new RESTEndpoint(framework) { @Override BundleContext getBundleContext() { return bundleContext; } }; rest.setMetacardTypes(Collections.singletonList(BasicTypes.BASIC_METACARD)); MimeTypeMapper mimeTypeMapper = mock(MimeTypeMapper.class); when(mimeTypeMapper.getMimeTypeForFileExtension("txt")).thenReturn("text/plain"); when(mimeTypeMapper.getMimeTypeForFileExtension("xml")).thenReturn("text/xml"); rest.setMimeTypeMapper(mimeTypeMapper); addMatchingService(rest, Arrays.asList(getSimpleTransformer())); List<Attachment> attachments = new ArrayList<>(); ContentDisposition contentDisposition = new ContentDisposition( "form-data; name=parse.resource; filename=C:\\DDF\\metacard.txt"); Attachment attachment = new Attachment("parse.resource", new ByteArrayInputStream("Some Text".getBytes()), contentDisposition); attachments.add(attachment); ContentDisposition contentDisposition1 = new ContentDisposition( "form-data; name=parse.metadata; filename=C:\\DDF\\metacard.xml"); Attachment attachment1 = new Attachment("parse.metadata", new ByteArrayInputStream("Some Text Again".getBytes()), contentDisposition1); attachments.add(attachment1); RESTEndpoint.CreateInfo createInfo = rest.parseAttachments(attachments, "xml"); assertThat(createInfo.getMetacard().getMetadata(), equalTo("Some Text Again")); ContentDisposition contentDisposition2 = new ContentDisposition( "form-data; name=metadata; filename=C:\\DDF\\metacard.xml"); Attachment attachment2 = new Attachment("metadata", new ByteArrayInputStream("<meta>beta</meta>".getBytes()), contentDisposition2); attachments.add(attachment2); ContentDisposition contentDisposition3 = new ContentDisposition( "form-data; name=foo; filename=C:\\DDF\\metacard.xml"); Attachment attachment3 = new Attachment("foo", new ByteArrayInputStream("bar".getBytes()), contentDisposition3); attachments.add(attachment3); createInfo = rest.parseAttachments(attachments, "xml"); assertThat(createInfo.getMetacard().getMetadata(), equalTo("<meta>beta</meta>")); assertThat(createInfo.getMetacard().getAttribute("foo"), equalTo(null)); } /** * Tests local retrieve with a null QueryResponse * * @throws Exception */ @Test(expected = ServerErrorException.class) public void testGetDocumentLocalNullQueryResponse() throws Exception { CatalogFramework framework = givenCatalogFramework(SAMPLE_ID); String transformer = mockTestSetup(framework, TestType.QUERY_RESPONSE_TEST); executeTest(framework, transformer, true, null); } /** * Tests federated retrieve with a null QueryResponse * * @throws Exception */ @Test(expected = ServerErrorException.class) public void testGetDocumentFedNullQueryResponse() throws Exception { CatalogFramework framework = givenCatalogFramework(SAMPLE_ID); String transformer = mockTestSetup(framework, TestType.QUERY_RESPONSE_TEST); executeTest(framework, transformer, false, null); } /** * Tests local retrieve with a null Metacard * * @throws Exception */ @Test(expected = ServerErrorException.class) public void testGetDocumentLocalNullMetacard() throws Exception { CatalogFramework framework = givenCatalogFramework(SAMPLE_ID); String transformer = mockTestSetup(framework, TestType.METACARD_TEST); executeTest(framework, transformer, true, null); } /** * Tests federated retrieve with a null Metacard * * @throws Exception */ @Test(expected = ServerErrorException.class) public void testGetDocumentFedNullMetacard() throws Exception { CatalogFramework framework = givenCatalogFramework(SAMPLE_ID); String transformer = mockTestSetup(framework, TestType.METACARD_TEST); executeTest(framework, transformer, false, null); } /** * Tests local retrieve with a successful response * * @throws Exception */ @Test public void testGetDocumentLocalSuccess() throws Exception { CatalogFramework framework = givenCatalogFramework(SAMPLE_ID); String transformer = mockTestSetup(framework, TestType.SUCCESS_TEST); Response response = executeTest(framework, transformer, true, null); String responseMessage = IOUtils.toString((ByteArrayInputStream) response.getEntity()); assertEquals(GET_STREAM, responseMessage); assertEquals(OK, response.getStatus()); assertEquals(GET_TYPE_OUTPUT, response.getMetadata() .toString()); } @Test public void testGetDocumentKml() throws Exception { CatalogFramework framework = givenCatalogFramework(SAMPLE_ID); String transformer = mockTestSetup(framework, TestType.KML_TEST); Response response = executeTest(framework, transformer, true, null); String responseMessage = IOUtils.toString((ByteArrayInputStream) response.getEntity()); assertEquals(GET_STREAM, responseMessage); assertEquals(OK, response.getStatus()); assertEquals(GET_KML_TYPE_OUTPUT, response.getMetadata() .toString()); } /** * Tests federated retrieve with a successful response * * @throws Exception */ @Test public void testGetDocumentFedSuccess() throws Exception { CatalogFramework framework = givenCatalogFramework(SAMPLE_ID); String transformer = mockTestSetup(framework, TestType.SUCCESS_TEST); Response response = executeTest(framework, transformer, false, null); String responseMessage = IOUtils.toString((ByteArrayInputStream) response.getEntity()); assertEquals(GET_STREAM, responseMessage); assertEquals(OK, response.getStatus()); assertEquals(GET_TYPE_OUTPUT, response.getMetadata() .toString()); } /** * Tests getting source information * * @throws Exception */ @Test public void testGetDocumentSourcesSuccess() throws Exception { final String localSourceId = "local"; final String fed1SourceId = "fed1"; final String fed2SourceId = "fed2"; final String version = "4.0"; final String jsonMimeTypeString = "application/json"; Set<ContentType> contentTypes = new HashSet<ContentType>(); contentTypes.add(new ContentTypeImpl("ct1", "v1")); contentTypes.add(new ContentTypeImpl("ct2", "v2")); contentTypes.add(new ContentTypeImpl("ct3", null)); JSONArray contentTypesInJSON = new JSONArray(); for (ContentType ct : contentTypes) { JSONObject ob = new JSONObject(); ob.put("name", ct.getName()); ob.put("version", ct.getVersion() != null ? ct.getVersion() : ""); contentTypesInJSON.add(ob); } Set<SourceDescriptor> sourceDescriptors = new HashSet<SourceDescriptor>(); SourceDescriptorImpl localDescriptor = new SourceDescriptorImpl(localSourceId, contentTypes); localDescriptor.setVersion(version); localDescriptor.setAvailable(true); SourceDescriptorImpl fed1Descriptor = new SourceDescriptorImpl(fed1SourceId, contentTypes); fed1Descriptor.setVersion(version); fed1Descriptor.setAvailable(true); SourceDescriptorImpl fed2Descriptor = new SourceDescriptorImpl(fed2SourceId, null); fed2Descriptor.setAvailable(true); sourceDescriptors.add(localDescriptor); sourceDescriptors.add(fed1Descriptor); sourceDescriptors.add(fed2Descriptor); SourceInfoResponse sourceInfoResponse = new SourceInfoResponseImpl(null, null, sourceDescriptors); CatalogFramework framework = mock(CatalogFramework.class); when(framework.getSourceInfo(isA(SourceInfoRequestEnterprise.class))).thenReturn( sourceInfoResponse); RESTEndpoint restEndpoint = new RESTEndpoint(framework); Response response = restEndpoint.getDocument(null, null); assertEquals(OK, response.getStatus()); assertEquals(jsonMimeTypeString, response.getMetadata() .get("Content-Type") .get(0)); String responseMessage = IOUtils.toString((ByteArrayInputStream) response.getEntity()); JSONArray srcList = (JSONArray) new JSONParser().parse(responseMessage); assertEquals(3, srcList.size()); for (Object o : srcList) { JSONObject src = (JSONObject) o; assertEquals(true, src.get("available")); String id = (String) src.get("id"); if (id.equals(localSourceId)) { assertThat((Iterable<Object>) src.get("contentTypes"), hasItems(contentTypesInJSON.toArray())); assertEquals(contentTypes.size(), ((JSONArray) src.get("contentTypes")).size()); assertEquals(version, src.get("version")); } else if (id.equals(fed1SourceId)) { assertThat((Iterable<Object>) src.get("contentTypes"), hasItems(contentTypesInJSON.toArray())); assertEquals(contentTypes.size(), ((JSONArray) src.get("contentTypes")).size()); assertEquals(version, src.get("version")); } else if (id.equals(fed2SourceId)) { assertEquals(0, ((JSONArray) src.get("contentTypes")).size()); assertEquals("", src.get("version")); } else { fail("Invalid ID returned"); } } } /** * Tests retrieving a local resource with a successful response * * @throws Exception */ @Test public void testGetDocumentResourceLocalSuccess() throws Exception { CatalogFramework framework = givenCatalogFramework(SAMPLE_ID); String transformer = mockTestSetup(framework, TestType.RESOURCE_TEST); Response response = executeTest(framework, transformer, true, null); String responseMessage = IOUtils.toString((ByteArrayInputStream) response.getEntity()); assertEquals(GET_STREAM, responseMessage); assertEquals(OK, response.getStatus()); assertEquals(GET_TYPE_OUTPUT, response.getMetadata() .toString()); } /** * Tests retrieving a federated resource with a successful response * * @throws Exception */ @Test public void testGetDocumentResourceFedSuccess() throws Exception { CatalogFramework framework = givenCatalogFramework(SAMPLE_ID); String transformer = mockTestSetup(framework, TestType.RESOURCE_TEST); Response response = executeTest(framework, transformer, false, null); String responseMessage = IOUtils.toString((ByteArrayInputStream) response.getEntity()); assertEquals(GET_STREAM, responseMessage); assertEquals(OK, response.getStatus()); assertEquals(GET_TYPE_OUTPUT, response.getMetadata() .toString()); } /** * Tests that a geojson input has its InputTransformer invoked by the REST endpoint to create * a metacard that is then converted to XML and returned from the REST endpoint. * * @throws Exception */ @Test public void testGetMetacardAsXml() throws Exception { String filename = "src/test/resources/ValidGeojson.json"; CatalogFramework framework = givenCatalogFramework(SAMPLE_ID); String metacardXml = "<metacard ns2:id=\"assigned-when-ingested\">\r\n" + "<type>type.metacard</type>\r\n" + "<string name=\"title\">\r\n" + "<value>Title goes here ...</value>\r\n" + "</string>\r\n" + "<string name=\"metadata\">\r\n" + "<value>metadata goes here ...</value>\r\n" + "</metacard>"; // Mock XmlMetacardTransformer that CatalogFramework will call to convert generated // metacard into XML to be returned from REST endpoint. final BinaryContent content = mock(BinaryContent.class); InputStream inputStream = new ByteArrayInputStream(metacardXml.getBytes(GET_OUTPUT_TYPE)); when(content.getInputStream()).thenReturn(inputStream); when(content.getMimeTypeValue()).thenReturn("application/json;id=geojson"); when(framework.transform(isA(Metacard.class), anyString(), isNull(Map.class))).thenAnswer( new Answer<BinaryContent>() { @Override public BinaryContent answer(InvocationOnMock invocation) throws Throwable { Object[] args = invocation.getArguments(); Metacard metacard = (Metacard) args[0]; return content; } }); RESTEndpoint restEndpoint = new RESTEndpoint(framework); // Add a MimeTypeToINputTransformer that the REST endpoint will call to create the metacard addMatchingService(restEndpoint, Arrays.asList(getSimpleTransformer())); restEndpoint.setTikaMimeTypeResolver(new TikaMimeTypeResolver()); FilterBuilder filterBuilder = new GeotoolsFilterBuilder(); restEndpoint.setFilterBuilder(filterBuilder); String json = "{\r\n" + " \"properties\": {\r\n" + " \"title\": \"myTitle\",\r\n" + " \"thumbnail\": \"CA==\",\r\n" + " \"resource-uri\": \"http://example.com\",\r\n" + " \"created\": \"2012-09-01T00:09:19.368+0000\",\r\n" + " \"metadata-content-type-version\": \"myVersion\",\r\n" + " \"metadata-content-type\": \"myType\",\r\n" + " \"metadata\": \"<xml>metadata goes here ...</xml>\",\r\n" + " \"modified\": \"2012-09-01T00:09:19.368+0000\"\r\n" + " },\r\n" + " \"type\": \"Feature\",\r\n" + " \"geometry\": {\r\n" + " \"type\": \"Point\",\r\n" + " \"coordinates\": [\r\n" + " 30.0,\r\n" + " 10.0\r\n" + " ]\r\n" + " }\r\n" + "} "; // Sample headers for a multipart body specifying a geojson file to have a metacard created for: // Content-Disposition: form-data; name="file"; filename="C:\DDF\geojson_valid.json" // Content-Type: application/json;id=geojson InputStream is = IOUtils.toInputStream(json); List<Attachment> attachments = new ArrayList<>(); ContentDisposition contentDisposition = new ContentDisposition( "form-data; name=file; filename=C:\\DDF\\geojson_valid.json"); Attachment attachment = new Attachment("file_part", is, contentDisposition); attachments.add(attachment); MediaType mediaType = new MediaType(MediaType.APPLICATION_JSON, "id=geojson"); MultipartBody multipartBody = new MultipartBody(attachments, mediaType, true); UriInfo uriInfo = createSpecificUriInfo(LOCAL_RETRIEVE_ADDRESS); Response response = restEndpoint.createMetacard(multipartBody, uriInfo, RESTEndpoint.DEFAULT_METACARD_TRANSFORMER); assertEquals(OK, response.getStatus()); InputStream responseEntity = (InputStream) response.getEntity(); String responseXml = IOUtils.toString(responseEntity); assertEquals(metacardXml, responseXml); } /** * Test using a Head request to find out if Range headers are supported and to get resource size of a local * resource for use when using Range headers. * * @throws Exception */ @Test public void testHeadRequestLocal() throws Exception { boolean isLocal = true; Response response = headTest(isLocal); assertEquals(NO_CONTENT, response.getStatus()); assertEquals(ACCEPT_RANGES_VALUE, response.getHeaderString(HEADER_ACCEPT_RANGES)); assertEquals(CONTENT_DISPOSITION_VALUE, response.getHeaderString(HEADER_CONTENT_DISPOSITION)); } /** * Test using a Head request to find out if Range headers are supported and to get resource size of a resource * at a federated site for use when using Range headers. * * @throws Exception */ @Test public void testHeadRequestFederated() throws Exception { boolean isLocal = false; Response response = headTest(isLocal); assertEquals(NO_CONTENT, response.getStatus()); assertEquals(ACCEPT_RANGES_VALUE, response.getHeaderString(HEADER_ACCEPT_RANGES)); assertEquals(CONTENT_DISPOSITION_VALUE, response.getHeaderString(HEADER_CONTENT_DISPOSITION)); } private Response headTest(boolean local) throws CatalogTransformerException, URISyntaxException, UnsupportedEncodingException, UnsupportedQueryException, SourceUnavailableException, FederationException, IngestException { MetacardImpl metacard = null; List<Result> list = new ArrayList<Result>(); Result result = mock(Result.class); InputStream inputStream = null; UriInfo uriInfo; Response response; CatalogFramework framework = givenCatalogFramework(SAMPLE_ID); list.add(result); QueryResponse queryResponse = mock(QueryResponse.class); when(queryResponse.getResults()).thenReturn(list); when(framework.query(isA(QueryRequest.class), isNull(FederationStrategy.class))).thenReturn( queryResponse); metacard = new MetacardImpl(); metacard.setSourceId(GET_SITENAME); when(result.getMetacard()).thenReturn(metacard); Resource resource = mock(Resource.class); inputStream = new ByteArrayInputStream(GET_STREAM.getBytes(GET_OUTPUT_TYPE)); when(resource.getInputStream()).thenReturn(inputStream); when(resource.getMimeTypeValue()).thenReturn(GET_MIME_TYPE); when(resource.getName()).thenReturn(GET_FILENAME); when(framework.transform(isA(Metacard.class), anyString(), isA(Map.class))).thenReturn( resource); RESTEndpoint restEndpoint = new RESTEndpoint(framework); restEndpoint.setTikaMimeTypeResolver(new TikaMimeTypeResolver()); FilterBuilder filterBuilder = new GeotoolsFilterBuilder(); restEndpoint.setFilterBuilder(filterBuilder); uriInfo = createSpecificUriInfo(LOCAL_RETRIEVE_ADDRESS); if (local) { response = restEndpoint.getHeaders(GET_ID, uriInfo, null); } else { response = restEndpoint.getHeaders(null, GET_ID, uriInfo, null); } return response; } /** * Creates a UriInfo with a user specified URL * * @param url * @return * @throws URISyntaxException */ protected UriInfo createSpecificUriInfo(String url) throws URISyntaxException { UriInfo uriInfo = mock(UriInfo.class); URI uri = new URI(url); when(uriInfo.getAbsolutePath()).thenReturn(uri); when(uriInfo.getQueryParameters()).thenReturn(mock(MultivaluedMap.class)); return uriInfo; } /** * Creates the mock setup for the GET tests above. Parameters provide the CatalogFramework, which will be * setup for the test, and also specify which test case is being run. * * @param framework * @param testType * @return * @throws Exception */ protected String mockTestSetup(CatalogFramework framework, TestType testType) throws Exception, ResourceNotSupportedException { String transformer = null; QueryResponse queryResponse = mock(QueryResponse.class); when(framework.query(isA(QueryRequest.class), isNull(FederationStrategy.class))).thenReturn( queryResponse); List<Result> list = null; MetacardImpl metacard = null; Result result = mock(Result.class); InputStream inputStream = null; switch (testType) { case QUERY_RESPONSE_TEST: when(queryResponse.getResults()).thenReturn(list); break; case METACARD_TEST: list = new ArrayList<Result>(); list.add(result); when(queryResponse.getResults()).thenReturn(list); when(result.getMetacard()).thenReturn(metacard); break; case RESOURCE_TEST: transformer = "resource"; /* FALLTHRU */ case SUCCESS_TEST: list = new ArrayList<Result>(); list.add(result); when(queryResponse.getResults()).thenReturn(list); metacard = new MetacardImpl(); metacard.setSourceId(GET_SITENAME); when(result.getMetacard()).thenReturn(metacard); Resource resource = mock(Resource.class); inputStream = new ByteArrayInputStream(GET_STREAM.getBytes(GET_OUTPUT_TYPE)); when(resource.getInputStream()).thenReturn(inputStream); when(resource.getMimeTypeValue()).thenReturn(GET_MIME_TYPE); when(resource.getName()).thenReturn(GET_FILENAME); when(framework.transform(isA(Metacard.class), anyString(), isA(Map.class))).thenReturn( resource); break; case KML_TEST: transformer = "kml"; list = new ArrayList<Result>(); list.add(result); when(queryResponse.getResults()).thenReturn(list); metacard = new MetacardImpl(); metacard.setSourceId(GET_SITENAME); when(result.getMetacard()).thenReturn(metacard); BinaryContent content = mock(BinaryContent.class); inputStream = new ByteArrayInputStream(GET_STREAM.getBytes(GET_OUTPUT_TYPE)); when(content.getInputStream()).thenReturn(inputStream); when(content.getMimeTypeValue()).thenReturn(GET_KML_MIME_TYPE); when(framework.transform(isA(Metacard.class), anyString(), isA(Map.class))).thenReturn( content); break; } return transformer; } private Response executeTest(CatalogFramework framework, String transformer, boolean local, HttpServletRequest request) throws URISyntaxException { RESTEndpoint restEndpoint = new RESTEndpoint(framework); restEndpoint.setTikaMimeTypeResolver(new TikaMimeTypeResolver()); FilterBuilder filterBuilder = new GeotoolsFilterBuilder(); restEndpoint.setFilterBuilder(filterBuilder); UriInfo uriInfo; Response response; if (local) { uriInfo = createSpecificUriInfo(LOCAL_RETRIEVE_ADDRESS); response = restEndpoint.getDocument(GET_ID, transformer, uriInfo, request); } else { uriInfo = createSpecificUriInfo(FED_RETRIEVE_ADDRESS); response = restEndpoint.getDocument(GET_SITENAME, GET_ID, transformer, uriInfo, request); } return response; } protected void assertExceptionThrown(Class<? extends Throwable> klass) throws IngestException, SourceUnavailableException, URISyntaxException { CatalogFramework framework = mock(CatalogFramework.class); when(framework.create(isA(CreateRequest.class))).thenThrow(klass); when(framework.create(isA(CreateStorageRequest.class))).thenThrow(klass); HttpHeaders headers = createHeaders(Arrays.asList(MediaType.APPLICATION_JSON)); RESTEndpoint rest = new RESTEndpoint(framework); addMatchingService(rest, Arrays.asList(getSimpleTransformer())); UriInfo info = givenUriInfo(SAMPLE_ID); try { rest.addDocument(headers, info, mock(HttpServletRequest.class), mock(MultipartBody.class), null, new ByteArrayInputStream("".getBytes())); fail(); } catch (ServerErrorException e) { if (klass.getName() .equals(SourceUnavailableException.class.getName())) { assertThat(e.getResponse() .getStatus(), equalTo(INTERNAL_SERVER_ERROR)); } else if (klass.getName() .equals(IngestException.class.getName())) { assertThat(e.getResponse() .getStatus(), equalTo(BAD_REQUEST)); } } } protected CatalogFramework givenCatalogFramework(String returnId) throws IngestException, SourceUnavailableException { CatalogFramework framework = mock(CatalogFramework.class); Metacard returnMetacard = mock(Metacard.class); when(returnMetacard.getId()).thenReturn(returnId); when(framework.create(isA(CreateRequest.class))).thenReturn( new CreateResponseImpl(null, null, Arrays.asList(returnMetacard))); when(framework.create(isA(CreateStorageRequest.class))).thenReturn( new CreateResponseImpl(null, null, Arrays.asList(returnMetacard))); return framework; } protected UriInfo givenUriInfo(String metacardId) throws URISyntaxException { UriInfo info = mock(UriInfo.class); UriBuilder builder = mock(UriBuilder.class); when(builder.path("/" + metacardId)).thenReturn(builder); when(builder.build()).thenReturn(new URI(ENDPOINT_ADDRESS)); when(info.getAbsolutePathBuilder()).thenReturn(builder); return info; } protected InputTransformer getMockInputTransformer() { InputTransformer inputTransformer = mock(InputTransformer.class); Metacard generatedMetacard = getSimpleMetacard(); try { when(inputTransformer.transform(isA(InputStream.class))).thenReturn(generatedMetacard); when(inputTransformer.transform(isA(InputStream.class), isA(String.class))).thenReturn( generatedMetacard); } catch (IOException e) { LOGGER.debug("Exception occurred during test", e); } catch (CatalogTransformerException e) { LOGGER.debug("Exception occurred during test", e); } return inputTransformer; } protected Metacard getSimpleMetacard() { MetacardImpl generatedMetacard = new MetacardImpl(); generatedMetacard.setMetadata(getSample()); generatedMetacard.setId(SAMPLE_ID); return generatedMetacard; } private InputTransformer getSimpleTransformer() { return new InputTransformer() { @Override public Metacard transform(InputStream input, String id) throws IOException, CatalogTransformerException { return getSimpleMetacard(); } @Override public Metacard transform(InputStream input) throws IOException, CatalogTransformerException { return getSimpleMetacard(); } }; } private MimeTypeToTransformerMapper addMatchingService(RESTEndpoint rest, List<InputTransformer> sortedListOfTransformers) { MimeTypeToTransformerMapper matchingService = mock(MimeTypeToTransformerMapper.class); when(matchingService.findMatches(eq(InputTransformer.class), isA(MimeType.class))).thenReturn((List) sortedListOfTransformers); rest.setMimeTypeToTransformerMapper(matchingService); return matchingService; } private HttpServletRequest createServletRequest(String bytesToSkip) { HttpServletRequest request = mock(HttpServletRequest.class); when(request.getHeader(HEADER_RANGE)).thenReturn("bytes=" + bytesToSkip + "-"); return request; } private HttpHeaders createHeaders(List<String> mimeTypeList) { HttpHeaders headers = mock(HttpHeaders.class); when(headers.getRequestHeader(HttpHeaders.CONTENT_TYPE)).thenReturn(mimeTypeList); return headers; } private String getSample() { return "<xml></xml>"; } protected enum TestType { QUERY_RESPONSE_TEST, METACARD_TEST, SUCCESS_TEST, RESOURCE_TEST, KML_TEST } }