/** * Copyright 2014 Flipkart Internet Pvt. Ltd. * * Licensed under the Apache 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://www.apache.org/licenses/LICENSE-2.0 * * 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 com.flipkart.foxtrot.server.resources; import com.fasterxml.jackson.core.type.TypeReference; import com.flipkart.foxtrot.common.Document; import com.flipkart.foxtrot.core.TestUtils; import com.flipkart.foxtrot.core.exception.FoxtrotExceptions; import com.flipkart.foxtrot.core.querystore.impl.ElasticsearchUtils; import com.flipkart.foxtrot.server.providers.exception.FoxtrotExceptionMapper; import com.sun.jersey.api.client.UniformInterfaceException; import com.sun.jersey.api.container.ContainerException; import com.sun.jersey.api.container.MappableContainerException; import com.yammer.dropwizard.validation.InvalidEntityException; import org.junit.Test; import org.mockito.Matchers; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.io.IOException; import java.util.*; import static org.junit.Assert.*; import static org.mockito.Matchers.anyListOf; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; /** * Created by rishabh.goyal on 04/05/14. */ public class DocumentResourceTest extends FoxtrotResourceTest { public DocumentResourceTest() throws Exception { super(); doReturn(true).when(getTableMetadataManager()).exists(anyString()); doReturn(TestUtils.TEST_TABLE).when(getTableMetadataManager()).get(anyString()); } @Override protected void setUpResources() throws Exception { addResource(new DocumentResource(getQueryStore())); addProvider(FoxtrotExceptionMapper.class); } @Test public void testSaveDocument() throws Exception { String id = UUID.randomUUID().toString(); Document document = new Document( id, System.currentTimeMillis(), getMapper().getNodeFactory().objectNode().put("hello", "world")); client().resource("/v1/document/" + TestUtils.TEST_TABLE_NAME).type(MediaType.APPLICATION_JSON_TYPE).post(document); getElasticsearchServer().refresh(ElasticsearchUtils.getIndices(TestUtils.TEST_TABLE_NAME)); Document response = getQueryStore().get(TestUtils.TEST_TABLE_NAME, id); compare(document, response); } @Test public void testSaveDocumentInternalError() throws Exception { String id = UUID.randomUUID().toString(); Document document = new Document( id, System.currentTimeMillis(), getMapper().getNodeFactory().objectNode().put("hello", "world")); doThrow(FoxtrotExceptions.createExecutionException("dummy", new IOException())) .when(getQueryStore()).save(anyString(), Matchers.<Document>any()); try { client().resource("/v1/document/" + TestUtils.TEST_TABLE_NAME).type(MediaType.APPLICATION_JSON_TYPE).post(document); fail(); } catch (UniformInterfaceException ex) { assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), ex.getResponse().getStatus()); } } @Test(expected = InvalidEntityException.class) public void testSaveDocumentNullId() throws Exception { Document document = new Document( null, System.currentTimeMillis(), getMapper().getNodeFactory().objectNode().put("hello", "world")); client().resource("/v1/document/" + TestUtils.TEST_TABLE_NAME).type(MediaType.APPLICATION_JSON_TYPE).post(document); } @Test(expected = InvalidEntityException.class) public void testSaveDocumentNullData() throws Exception { Document document = new Document( UUID.randomUUID().toString(), System.currentTimeMillis(), null); client().resource("/v1/document/" + TestUtils.TEST_TABLE_NAME).type(MediaType.APPLICATION_JSON_TYPE).post(document); } @Test(expected = ContainerException.class) public void testSaveDocumentUnknownObject() throws Exception { client().resource("/v1/document/" + TestUtils.TEST_TABLE_NAME).type(MediaType.APPLICATION_JSON_TYPE).post("hello"); } @Test(expected = InvalidEntityException.class) public void testSaveDocumentEmptyJson() throws Exception { client().resource("/v1/document/" + TestUtils.TEST_TABLE_NAME).type(MediaType.APPLICATION_JSON_TYPE).post("{}"); } @Test public void testSaveDocuments() throws Exception { List<Document> documents = new ArrayList<Document>(); String id1 = UUID.randomUUID().toString(); Document document1 = new Document(id1, System.currentTimeMillis(), getMapper().getNodeFactory().objectNode().put("D", "data")); String id2 = UUID.randomUUID().toString(); Document document2 = new Document(id2, System.currentTimeMillis(), getMapper().getNodeFactory().objectNode().put("D", "data")); documents.add(document1); documents.add(document2); client().resource(String.format("/v1/document/%s/bulk", TestUtils.TEST_TABLE_NAME)).type(MediaType.APPLICATION_JSON_TYPE).post(documents); getElasticsearchServer().refresh(ElasticsearchUtils.getIndices(TestUtils.TEST_TABLE_NAME)); compare(document1, getQueryStore().get(TestUtils.TEST_TABLE_NAME, id1)); compare(document2, getQueryStore().get(TestUtils.TEST_TABLE_NAME, id2)); } @Test public void testSaveDocumentsInternalError() throws Exception { List<Document> documents = new ArrayList<Document>(); String id1 = UUID.randomUUID().toString(); Document document1 = new Document(id1, System.currentTimeMillis(), getMapper().getNodeFactory().objectNode().put("D", "data")); String id2 = UUID.randomUUID().toString(); Document document2 = new Document(id2, System.currentTimeMillis(), getMapper().getNodeFactory().objectNode().put("D", "data")); documents.add(document1); documents.add(document2); doThrow(FoxtrotExceptions.createExecutionException("dummy", new IOException())) .when(getQueryStore()).save(anyString(), anyListOf(Document.class)); try { client().resource(String.format("/v1/document/%s/bulk", TestUtils.TEST_TABLE_NAME)).type(MediaType.APPLICATION_JSON_TYPE).post(documents); fail(); } catch (UniformInterfaceException ex) { assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), ex.getResponse().getStatus()); } } @Test(expected = InvalidEntityException.class) public void testSaveDocumentsNullDocuments() throws Exception { List<Document> documents = null; client().resource(String.format("/v1/document/%s/bulk", TestUtils.TEST_TABLE_NAME)).type(MediaType.APPLICATION_JSON_TYPE).post(documents); } @Test public void testSaveDocumentsNullDocument() throws Exception { List<Document> documents = new Vector<Document>(); documents.add(null); documents.add(new Document(UUID.randomUUID().toString(), System.currentTimeMillis(), getMapper().getNodeFactory().objectNode().put("d", "d"))); try { client().resource(String.format("/v1/document/%s/bulk", TestUtils.TEST_TABLE_NAME)) .type(MediaType.APPLICATION_JSON_TYPE) .post(documents); fail(); } catch (UniformInterfaceException ex) { assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), ex.getResponse().getStatus()); } } @Test public void testSaveDocumentsNullId() throws Exception { List<Document> documents = new Vector<Document>(); documents.add(new Document(null, System.currentTimeMillis(), getMapper().getNodeFactory().objectNode().put("d", "d"))); try { client().resource(String.format("/v1/document/%s/bulk", TestUtils.TEST_TABLE_NAME)) .type(MediaType.APPLICATION_JSON_TYPE) .post(documents); fail(); } catch (UniformInterfaceException ex) { assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), ex.getResponse().getStatus()); } } @Test public void testSaveDocumentsNullData() throws Exception { List<Document> documents = new Vector<Document>(); documents.add(new Document(UUID.randomUUID().toString(), System.currentTimeMillis(), null)); try { client().resource(String.format("/v1/document/%s/bulk", TestUtils.TEST_TABLE_NAME)) .type(MediaType.APPLICATION_JSON_TYPE) .post(documents); fail(); } catch (UniformInterfaceException ex) { assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), ex.getResponse().getStatus()); } } @Test(expected = MappableContainerException.class) public void testSaveDocumentsInvalidRequestObject() throws Exception { client().resource(String.format("/v1/document/%s/bulk", TestUtils.TEST_TABLE_NAME)) .type(MediaType.APPLICATION_JSON_TYPE) .post("Hello"); } @Test public void testSaveDocumentsEmptyList() throws Exception { try { client().resource(String.format("/v1/document/%s/bulk", TestUtils.TEST_TABLE_NAME)) .type(MediaType.APPLICATION_JSON_TYPE) .post("[]"); fail(); } catch (UniformInterfaceException ex) { assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), ex.getResponse().getStatus()); } } @Test public void testGetDocument() throws Exception { String id = UUID.randomUUID().toString(); Document document = new Document(id, System.currentTimeMillis(), getMapper().getNodeFactory().objectNode().put("D", "data")); getQueryStore().save(TestUtils.TEST_TABLE_NAME, document); getElasticsearchServer().refresh(ElasticsearchUtils.getIndices(TestUtils.TEST_TABLE_NAME)); Document response = client().resource(String.format("/v1/document/%s/%s", TestUtils.TEST_TABLE_NAME, id)) .get(Document.class); compare(document, response); } @Test public void testGetDocumentMissingId() throws Exception { String id = UUID.randomUUID().toString(); try { client().resource(String.format("/v1/document/%s/%s", TestUtils.TEST_TABLE_NAME, id)) .get(Document.class); fail(); } catch (UniformInterfaceException ex) { assertEquals(Response.Status.NOT_FOUND.getStatusCode(), ex.getResponse().getStatus()); } } @Test public void testGetDocumentInternalError() throws Exception { String id = UUID.randomUUID().toString(); try { doThrow(FoxtrotExceptions.createExecutionException("dummy", new IOException())) .when(getQueryStore()).get(anyString(), anyString()); client().resource(String.format("/v1/document/%s/%s", TestUtils.TEST_TABLE_NAME, id)) .get(Document.class); fail(); } catch (UniformInterfaceException ex) { assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), ex.getResponse().getStatus()); } } @Test public void testGetDocuments() throws Exception { List<Document> documents = new ArrayList<Document>(); String id1 = UUID.randomUUID().toString(); Document document1 = new Document(id1, System.currentTimeMillis(), getMapper().getNodeFactory().objectNode().put("D", "data")); String id2 = UUID.randomUUID().toString(); Document document2 = new Document(id2, System.currentTimeMillis(), getMapper().getNodeFactory().objectNode().put("D", "data")); documents.add(document1); documents.add(document2); getQueryStore().save(TestUtils.TEST_TABLE_NAME, documents); getElasticsearchServer().refresh(ElasticsearchUtils.getIndices(TestUtils.TEST_TABLE_NAME)); String response = client().resource(String.format("/v1/document/%s", TestUtils.TEST_TABLE_NAME)) .queryParam("id", id1) .queryParam("id", id2) .get(String.class); String expectedResponse = getMapper().writeValueAsString(documents); assertEquals(expectedResponse, response); } @Test public void testGetDocumentsNoIds() throws Exception { String response = client().resource(String.format("/v1/document/%s", TestUtils.TEST_TABLE_NAME)) .get(String.class); String expectedResponse = getMapper().writeValueAsString(new ArrayList<Document>()); assertEquals(expectedResponse, response); } @Test public void testGetDocumentsMissingIds() throws Exception { try { client().resource(String.format("/v1/document/%s", TestUtils.TEST_TABLE_NAME)) .queryParam("id", UUID.randomUUID().toString()) .get(String.class); fail(); } catch (UniformInterfaceException ex) { assertEquals(Response.Status.NOT_FOUND.getStatusCode(), ex.getResponse().getStatus()); } } @Test public void testGetDocumentsInternalError() throws Exception { try { doThrow(FoxtrotExceptions.createExecutionException("dummy", new IOException())) .when(getQueryStore()).getAll(anyString(), anyListOf(String.class)); client().resource(String.format("/v1/document/%s", TestUtils.TEST_TABLE_NAME)) .queryParam("id", UUID.randomUUID().toString()) .get(String.class); fail(); } catch (UniformInterfaceException ex) { assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), ex.getResponse().getStatus()); } } public void compare(Document expected, Document actual) throws Exception { assertNotNull(expected); assertNotNull(actual); assertNotNull("Actual document Id should not be null", actual.getId()); assertNotNull("Actual document data should not be null", actual.getData()); assertEquals("Actual Doc Id should match expected Doc Id", expected.getId(), actual.getId()); assertEquals("Actual Doc Timestamp should match expected Doc Timestamp", expected.getTimestamp(), actual.getTimestamp()); Map<String, Object> expectedMap = getMapper().convertValue(expected.getData(), new TypeReference<HashMap<String, Object>>() { }); Map<String, Object> actualMap = getMapper().convertValue(actual.getData(), new TypeReference<HashMap<String, Object>>() { }); assertEquals("Actual data should match expected data", expectedMap, actualMap); } }