com.strategicgains.docussandra.controller.IndexControllerTest.java Source code

Java tutorial

Introduction

Here is the source code for com.strategicgains.docussandra.controller.IndexControllerTest.java

Source

package com.strategicgains.docussandra.controller;

/*
 * Copyright 2015 udeyoje.
 *
 * 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.
 */
import com.jayway.restassured.RestAssured;
import static com.jayway.restassured.RestAssured.expect;
import static com.jayway.restassured.RestAssured.given;
import com.jayway.restassured.response.ResponseOptions;
import com.strategicgains.docussandra.cache.CacheFactory;
import com.strategicgains.docussandra.domain.Database;
import com.strategicgains.docussandra.domain.Document;
import com.strategicgains.docussandra.domain.Index;
import com.strategicgains.docussandra.domain.Table;
import com.strategicgains.docussandra.persistence.impl.DocumentRepositoryImpl;
import org.junit.BeforeClass;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.strategicgains.docussandra.testhelper.Fixtures;
import java.util.List;
import org.apache.commons.lang3.time.StopWatch;
import static org.hamcrest.Matchers.*;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import static org.junit.Assert.fail;
import org.junit.Before;
import org.junit.Test;
import testhelper.RestExpressManager;

/**
 *
 * @author udeyoje
 */
public class IndexControllerTest {

    private static final Logger LOGGER = LoggerFactory.getLogger(IndexControllerTest.class);
    private static final String BASE_URI = "http://localhost";
    private static final int PORT = 19080;
    private static Fixtures f;
    private JSONParser parser = new JSONParser();

    public IndexControllerTest() throws Exception {
    }

    /**
     * Initialization that is performed once before any of the tests in this
     * class are executed.
     *
     * @throws Exception
     */
    @BeforeClass
    public static void beforeClass() throws Exception {
        RestAssured.baseURI = BASE_URI;
        RestAssured.port = PORT;
        f = Fixtures.getInstance();
        RestExpressManager.getManager().ensureRestExpressRunning();
    }

    @Before
    public void beforeTest() {
        f.clearTestTables();
        CacheFactory.clearAllCaches();
        Database testDb = Fixtures.createTestDatabase();
        f.insertDatabase(testDb);
        Table testTable = Fixtures.createTestTable();
        f.insertTable(testTable);
        RestAssured.basePath = "/" + testDb.name() + "/" + testTable.name() + "/indexes";
    }

    /**
     * Cleanup that is performed once after all of the tests in this class are
     * executed.
     */
    @AfterClass
    public static void afterClass() {
        f.clearTestTables();
    }

    /**
     * Cleanup that is performed after each test is executed.
     */
    @After
    public void afterTest() {

    }

    /**
     * Tests that the GET /{databases}/{setTable}/indexes/{index} properly
     * retrieves an existing index.
     */
    @Test
    public void getIndexTest() {
        Index testIndex = Fixtures.createTestIndexOneField();
        f.insertIndex(testIndex);
        ResponseOptions result = expect().statusCode(200).body("name", equalTo(testIndex.getName()))
                .body("fields", notNullValue()).body("createdAt", notNullValue()).body("updatedAt", notNullValue())
                .when().get(testIndex.getName()).andReturn();

        LOGGER.info(result.body().prettyPrint());
    }

    /**
     * Tests that the POST /{databases}/{setTable}/indexes/ endpoint properly
     * creates a index.
     */
    @Test
    public void postIndexTest() throws InterruptedException {
        Index testIndex = Fixtures.createTestIndexOneField();
        String indexStr = "{" + "\"fields\" : [\"" + testIndex.getFieldsValues().get(0) + "\"], \"name\" : \""
                + testIndex.getName() + "\"}";

        //act
        given().body(indexStr).expect().statusCode(201).body("index.name", equalTo(testIndex.getName()))
                .body("index.fields", notNullValue()).body("index.createdAt", notNullValue())
                .body("index.updatedAt", notNullValue()).body("index.active", equalTo(false))
                .body("id", notNullValue()).body("dateStarted", notNullValue())
                .body("statusLastUpdatedAt", notNullValue()).body("totalRecords", equalTo(0))
                .body("recordsCompleted", equalTo(0)).when().post("/" + testIndex.getName());

        Thread.sleep(100);//sleep for a hair to let the indexing complete

        //check self (index endpoint)
        expect().statusCode(200).body("name", equalTo(testIndex.getName())).body("fields", notNullValue())
                .body("createdAt", notNullValue()).body("updatedAt", notNullValue()).body("active", equalTo(true))
                .get("/" + testIndex.getName());
    }

    /**
     * Tests that the POST /{databases}/{setTable}/indexes/ endpoint properly
     * creates a index.
     */
    @Test
    public void postIndexAllFieldsTest() throws InterruptedException {
        Index testIndex = Fixtures.createTestIndexAllFieldTypes();
        String indexStr = Fixtures.generateIndexCreationStringWithFields(testIndex);

        //act
        given().body(indexStr).expect().statusCode(201).body("index.name", equalTo(testIndex.getName()))
                .body("index.fields", notNullValue())
                .body("index.fields[0].field", equalTo(testIndex.getFields().get(0).getField()))
                .body("index.fields[0].type", equalTo(testIndex.getFields().get(0).getType().toString()))
                .body("index.fields[1].field", equalTo(testIndex.getFields().get(1).getField()))
                .body("index.fields[1].type", equalTo(testIndex.getFields().get(1).getType().toString()))
                .body("index.fields[2].field", equalTo(testIndex.getFields().get(2).getField()))
                .body("index.fields[2].type", equalTo(testIndex.getFields().get(2).getType().toString()))
                .body("index.fields[3].field", equalTo(testIndex.getFields().get(3).getField()))
                .body("index.fields[3].type", equalTo(testIndex.getFields().get(3).getType().toString()))
                .body("index.fields[4].field", equalTo(testIndex.getFields().get(4).getField()))
                .body("index.fields[4].type", equalTo(testIndex.getFields().get(4).getType().toString()))
                .body("index.fields[5].field", equalTo(testIndex.getFields().get(5).getField()))
                .body("index.fields[5].type", equalTo(testIndex.getFields().get(5).getType().toString()))
                .body("index.fields[6].field", equalTo(testIndex.getFields().get(6).getField()))
                .body("index.fields[6].type", equalTo(testIndex.getFields().get(6).getType().toString()))
                .body("index.createdAt", notNullValue()).body("index.updatedAt", notNullValue())
                .body("index.active", equalTo(false)).body("id", notNullValue()).body("dateStarted", notNullValue())
                .body("statusLastUpdatedAt", notNullValue()).body("totalRecords", equalTo(0))
                .body("recordsCompleted", equalTo(0)).when().log().ifValidationFails()
                .post("/" + testIndex.getName());

        Thread.sleep(100);//sleep for a hair to let the indexing complete

        //check self (index endpoint)
        expect().statusCode(200).body("name", equalTo(testIndex.getName())).body("fields", notNullValue())
                .body("fields[0].field", equalTo(testIndex.getFields().get(0).getField()))
                .body("fields[0].type", equalTo(testIndex.getFields().get(0).getType().toString()))
                .body("fields[1].field", equalTo(testIndex.getFields().get(1).getField()))
                .body("fields[1].type", equalTo(testIndex.getFields().get(1).getType().toString()))
                .body("fields[2].field", equalTo(testIndex.getFields().get(2).getField()))
                .body("fields[2].type", equalTo(testIndex.getFields().get(2).getType().toString()))
                .body("fields[3].field", equalTo(testIndex.getFields().get(3).getField()))
                .body("fields[3].type", equalTo(testIndex.getFields().get(3).getType().toString()))
                .body("fields[4].field", equalTo(testIndex.getFields().get(4).getField()))
                .body("fields[4].type", equalTo(testIndex.getFields().get(4).getType().toString()))
                .body("fields[5].field", equalTo(testIndex.getFields().get(5).getField()))
                .body("fields[5].type", equalTo(testIndex.getFields().get(5).getType().toString()))
                .body("fields[6].field", equalTo(testIndex.getFields().get(6).getField()))
                .body("fields[6].type", equalTo(testIndex.getFields().get(6).getType().toString()))
                .body("createdAt", notNullValue()).body("updatedAt", notNullValue()).body("active", equalTo(true))
                .get("/" + testIndex.getName());
    }

    /**
     * Tests that the POST /{databases}/{setTable}/indexes/ endpoint properly
     * creates a index and that the
     * GET/{database}/{setTable}/index_status/{status_id} endpoint is working.
     */
    @Test
    public void postIndexAndCheckStatusTest() throws InterruptedException {
        Index testIndex = Fixtures.createTestIndexOneField();
        String indexStr = "{" + "\"fields\" : [\"" + testIndex.getFieldsValues().get(0) + "\"]," + "\"name\" : \""
                + testIndex.getName() + "\"}";

        //act
        ResponseOptions response = given().body(indexStr).expect().statusCode(201)
                .body("index.name", equalTo(testIndex.getName())).body("index.fields", notNullValue())
                .body("index.createdAt", notNullValue()).body("index.updatedAt", notNullValue())
                .body("index.active", equalTo(false))//should not yet be active
                .body("id", notNullValue()).body("dateStarted", notNullValue())
                .body("statusLastUpdatedAt", notNullValue()).body("eta", notNullValue())
                .body("precentComplete", notNullValue()).body("totalRecords", equalTo(0))
                .body("recordsCompleted", equalTo(0)).when().post("/" + testIndex.getName()).andReturn();

        Thread.sleep(100);//sleep for a hair to let the indexing complete

        String restAssuredBasePath = RestAssured.basePath;
        try {
            //get the uuid from the response
            String uuidString = response.getBody().jsonPath().get("id");
            RestAssured.basePath = "/" + testIndex.getDatabaseName() + "/" + testIndex.getTableName()
                    + "/index_status/";
            ResponseOptions res = expect().statusCode(200).body("id", equalTo(uuidString))
                    .body("dateStarted", notNullValue()).body("statusLastUpdatedAt", notNullValue())
                    .body("eta", notNullValue()).body("precentComplete", notNullValue())
                    .body("index", notNullValue()).body("index.active", equalTo(true))//should now be active
                    .body("totalRecords", notNullValue()).body("recordsCompleted", notNullValue()).when()
                    .get(uuidString).andReturn();//check status (index_status endpoint)
            LOGGER.debug("Status Response: " + res.getBody().prettyPrint());
        } finally {
            RestAssured.basePath = restAssuredBasePath;
        }
    }

    /**
     * Tests that the POST /{databases}/{setTable}/indexes/ endpoint properly
     * creates a index and that the
     * GET/{database}/{setTable}/index_status/{status_id} endpoint is working.
     */
    @Test
    public void createDataThenPostIndexAndCheckStatusTest() throws InterruptedException, Exception {
        String restAssuredBasePath = RestAssured.basePath;
        Database testDb = Fixtures.createTestPlayersDatabase();
        Table testTable = Fixtures.createTestPlayersTable();
        List<Document> docs = Fixtures.getBulkDocuments("./src/test/resources/players-short.json", testTable);
        try {
            //data insert          
            f.insertDatabase(testDb);
            f.insertTable(testTable);
            f.insertDocuments(docs);//put in a ton of data directly into the db
            Index lastname = Fixtures.createTestPlayersIndexLastName();
            String indexStr = "{" + "\"fields\" : [\"" + lastname.getFieldsValues().get(0) + "\"],"
                    + "\"name\" : \"" + lastname.getName() + "\"}";
            RestAssured.basePath = "/" + lastname.getDatabaseName() + "/" + lastname.getTableName() + "/indexes";
            //act -- create index
            ResponseOptions response = given().body(indexStr).expect().statusCode(201)
                    .body("index.name", equalTo(lastname.getName())).body("index.fields", notNullValue())
                    .body("index.createdAt", notNullValue()).body("index.updatedAt", notNullValue())
                    .body("index.active", equalTo(false))//should not yet be active
                    .body("id", notNullValue()).body("dateStarted", notNullValue())
                    .body("statusLastUpdatedAt", notNullValue()).body("eta", notNullValue())
                    .body("precentComplete", notNullValue()).body("totalRecords", equalTo(3308))
                    .body("recordsCompleted", equalTo(0)).when().post("/" + lastname.getName()).andReturn();

            //start a timer
            StopWatch sw = new StopWatch();
            sw.start();

            //check the status endpoint to make sure it got created
            //get the uuid from the response
            String uuidString = response.getBody().jsonPath().get("id");
            RestAssured.basePath = "/" + lastname.getDatabaseName() + "/" + lastname.getTableName()
                    + "/index_status/";
            ResponseOptions res = expect().statusCode(200).body("id", equalTo(uuidString))
                    .body("dateStarted", notNullValue()).body("statusLastUpdatedAt", notNullValue())
                    .body("eta", notNullValue()).body("precentComplete", notNullValue())
                    .body("index", notNullValue()).body("index.active", notNullValue())
                    .body("index.active", equalTo(false))//should not yet be active
                    .body("recordsCompleted", notNullValue()).when().get(uuidString).andReturn();
            LOGGER.debug("Status Response: " + res.getBody().prettyPrint());

            boolean active = false;
            while (!active) {
                //poll the status until it is active to make sure an index did in fact get created
                res = expect().statusCode(200).body("id", equalTo(uuidString)).body("dateStarted", notNullValue())
                        .body("statusLastUpdatedAt", notNullValue()).body("eta", notNullValue())
                        .body("precentComplete", notNullValue()).body("index", notNullValue())
                        .body("index.active", notNullValue()).body("recordsCompleted", notNullValue()).when()
                        .get(uuidString).andReturn();
                LOGGER.debug("Status Response: " + res.getBody().prettyPrint());
                active = res.getBody().jsonPath().get("index.active");
                if (active) {
                    sw.stop();
                    break;
                }
                LOGGER.debug("Waiting for index to go active for: " + sw.getTime());
                if (sw.getTime() >= 60000) {
                    fail("Index took too long to create");
                }
                Thread.sleep(2000);
            }
            LOGGER.info("It took: " + (sw.getTime() / 1000) + " seconds to create the index.");

        } finally {
            RestAssured.basePath = restAssuredBasePath;
            //clean up
            DocumentRepositoryImpl docrepo = new DocumentRepositoryImpl(f.getSession());
            for (Document d : docs) {
                try {
                    docrepo.delete(d);
                } catch (Exception e) {
                    ;//eh -- the doc probably never got created
                }
            }
        }
    }

    /**
     * Tests that the POST /{databases}/{setTable}/indexes/ endpoint properly
     * creates a index, setting errors to the index status table and that the
     * GET/{database}/{setTable}/index_status/{status_id} endpoint is working.
     */
    @Test
    public void createBadDataThenPostIndexAndCheckStatusTest() throws InterruptedException, Exception {
        String restAssuredBasePath = RestAssured.basePath;
        Database testDb = Fixtures.createTestPlayersDatabase();
        Table testTable = Fixtures.createTestPlayersTable();
        List<Document> docs = Fixtures.getBulkDocuments("./src/test/resources/players-short.json", testTable);
        //botch a doc
        Document badDoc = docs.get(0);
        //the year field is now text
        badDoc.object(
                "{\"SOURCE\":\"kffl\",\"LINK\":\"http://www.kffl.com/gnews.php?id=796662-eagles-michael-vick-showed-quick-release\",\"CREATEDON\":\"July, 07 2012 00:00:00\",\"ROOKIEYEAR\":\"TWO THOUSAND AND ONE\",\"NAMEFIRST\":\"Michael\",\"POSITION\":\"QB\",\"NAMEFULL\":\"Michael Vick\",\"TEAM\":\"PHI\",\"TITLE\":\"Michael Vick showed quick release\",\"NAMELAST\":\"Vick\"}");
        docs.set(0, badDoc);
        try {
            //data insert          
            f.insertDatabase(testDb);
            f.insertTable(testTable);
            f.insertDocuments(docs);//put in a ton of data directly into the db
            Index rookieyear = Fixtures.createTestPlayersIndexRookieYear();

            String indexString = Fixtures.generateIndexCreationStringWithFields(rookieyear);
            RestAssured.basePath = "/" + rookieyear.getDatabaseName() + "/" + rookieyear.getTableName()
                    + "/indexes";
            //act -- create index
            ResponseOptions response = given().body(indexString).expect().statusCode(201)
                    .body("index.name", equalTo(rookieyear.getName())).body("index.fields", notNullValue())
                    .body("index.createdAt", notNullValue()).body("index.updatedAt", notNullValue())
                    .body("index.active", equalTo(false))//should not yet be active
                    .body("id", notNullValue()).body("dateStarted", notNullValue())
                    .body("statusLastUpdatedAt", notNullValue()).body("eta", notNullValue())
                    .body("precentComplete", notNullValue()).body("totalRecords", equalTo(3308))
                    .body("recordsCompleted", equalTo(0)).when().post("/" + rookieyear.getName()).andReturn();

            //start a timer
            StopWatch sw = new StopWatch();
            sw.start();

            //check the status endpoint to make sure it got created
            //get the uuid from the response
            String uuidString = response.getBody().jsonPath().get("id");
            RestAssured.basePath = "/" + rookieyear.getDatabaseName() + "/" + rookieyear.getTableName()
                    + "/index_status/";
            ResponseOptions res = expect().statusCode(200).body("id", equalTo(uuidString))
                    .body("dateStarted", notNullValue()).body("statusLastUpdatedAt", notNullValue())
                    .body("eta", notNullValue()).body("precentComplete", notNullValue())
                    .body("index", notNullValue()).body("index.active", notNullValue())
                    .body("index.active", equalTo(false))//should not yet be active
                    .body("recordsCompleted", notNullValue()).when().get(uuidString).andReturn();
            LOGGER.debug("Status Response: " + res.getBody().prettyPrint());

            boolean active = false;
            while (!active) {
                //poll the status until it is active to make sure an index did in fact get created
                res = expect().statusCode(200).body("id", equalTo(uuidString)).body("dateStarted", notNullValue())
                        .body("statusLastUpdatedAt", notNullValue()).body("eta", notNullValue())
                        .body("precentComplete", notNullValue()).body("index", notNullValue())
                        .body("index.active", notNullValue()).body("recordsCompleted", notNullValue()).when()
                        .get(uuidString).andReturn();
                LOGGER.debug("Status Response: " + res.getBody().prettyPrint());
                active = res.getBody().jsonPath().get("index.active");
                if (active) {
                    sw.stop();
                    break;
                }
                LOGGER.debug("Waiting for index to go active for: " + sw.getTime());
                if (sw.getTime() >= 60000) {
                    fail("Index took too long to create: " + sw.getTime());
                }
                Thread.sleep(2000);
            }
            LOGGER.info("It took: " + (sw.getTime() / 1000) + " seconds to create the index.");

            //once it is active, lets check and make sure we have an error in the status table for our bad doc -- side note: there are tons more errors than our intentional one in this dataset
            res = expect().statusCode(200).body("id", equalTo(uuidString)).body("dateStarted", notNullValue())
                    .body("statusLastUpdatedAt", notNullValue()).body("eta", notNullValue())
                    .body("precentComplete", notNullValue()).body("index", notNullValue())
                    .body("index.active", notNullValue()).body("recordsCompleted", notNullValue()).when()
                    .get(uuidString).andReturn();
            LOGGER.debug("Status Response: " + res.getBody().prettyPrint());
            Assert.assertTrue(res.getBody().prettyPrint().contains("error"));
            Assert.assertTrue(
                    res.getBody().prettyPrint().contains("796662-eagles-michael-vick-showed-quick-release"));

        } finally {
            RestAssured.basePath = restAssuredBasePath;
            //clean up
            DocumentRepositoryImpl docrepo = new DocumentRepositoryImpl(f.getSession());
            for (Document d : docs) {
                try {
                    docrepo.delete(d);
                } catch (Exception e) {
                    ;//eh -- the doc probably never got created
                }
            }
        }
    }

    /**
     * Tests that the POST /{databases}/{setTable}/indexes/ endpoint properly
     * creates a index and that the GET/{database}/{setTable}/index_status/
     * endpoint is working.
     */
    @Test
    public void postIndexAndCheckStatusAllTest() throws Exception {
        String restAssuredBasePath = RestAssured.basePath;
        try {
            //data insert
            Database testDb = Fixtures.createTestPlayersDatabase();
            Table testTable = Fixtures.createTestPlayersTable();
            f.insertDatabase(testDb);
            f.insertTable(testTable);
            List<Document> docs = Fixtures.getBulkDocuments("./src/test/resources/players-short.json", testTable);
            f.insertDocuments(docs);//put in a ton of data directly into the db
            Index lastname = Fixtures.createTestPlayersIndexLastName();
            String indexString = "{" + "\"fields\" : [\"" + lastname.getFieldsValues().get(0) + "\"],"
                    + "\"name\" : \"" + lastname.getName() + "\"}";
            RestAssured.basePath = "/" + lastname.getDatabaseName() + "/" + lastname.getTableName() + "/indexes";
            //act -- create index
            given().body(indexString).expect().statusCode(201).body("index.name", equalTo(lastname.getName()))
                    .body("index.fields", notNullValue()).body("index.createdAt", notNullValue())
                    .body("index.updatedAt", notNullValue()).body("index.active", equalTo(false))//should not yet be active
                    .body("id", notNullValue()).body("dateStarted", notNullValue())
                    .body("statusLastUpdatedAt", notNullValue()).body("eta", notNullValue())
                    .body("precentComplete", notNullValue()).body("totalRecords", equalTo(3308))
                    .body("recordsCompleted", equalTo(0)).when().log().ifValidationFails()
                    .post("/" + lastname.getName());

            //start a timer
            StopWatch sw = new StopWatch();
            sw.start();

            RestAssured.basePath = "/index_status/";

            //check to make sure it shows as present at least once
            ResponseOptions res = expect().statusCode(200)
                    .body("_embedded.indexcreatedevents[0].id", notNullValue())
                    .body("_embedded.indexcreatedevents[0].dateStarted", notNullValue())
                    .body("_embedded.indexcreatedevents[0].statusLastUpdatedAt", notNullValue())
                    .body("_embedded.indexcreatedevents[0].eta", notNullValue())
                    .body("_embedded.indexcreatedevents[0].index", notNullValue())
                    .body("_embedded.indexcreatedevents[0].index.active", equalTo(false))//should not yet be active
                    .body("_embedded.indexcreatedevents[0].totalRecords", notNullValue())
                    .body("_embedded.indexcreatedevents[0].recordsCompleted", notNullValue())
                    .body("_embedded.indexcreatedevents[0].precentComplete", notNullValue()).when().log()
                    .ifValidationFails().get("/").andReturn();
            LOGGER.debug("Status Response: " + res.getBody().prettyPrint());
            //wait for it to dissapear (meaning it's gone active)
            boolean active = false;
            while (!active) {
                res = expect().statusCode(200).when().get("/").andReturn();
                String body = res.getBody().prettyPrint();
                LOGGER.debug("Status Response: " + body);

                JSONObject bodyObject = (JSONObject) parser.parse(body);
                JSONObject embedded = (JSONObject) bodyObject.get("_embedded");
                JSONArray resultSet = (JSONArray) embedded.get("indexcreatedevents");
                if (resultSet.isEmpty()) {
                    active = true;
                    sw.stop();
                    break;
                }
                LOGGER.debug("Waiting for index to go active for: " + sw.getTime());
                if (sw.getTime() >= 60000) {
                    fail("Index took too long to create");
                }
                Thread.sleep(2000);
            }
            LOGGER.info("It took: " + (sw.getTime() / 1000) + " seconds to create the index.");

        } finally {
            RestAssured.basePath = restAssuredBasePath;
        }
    }

    /**
     * Tests that the DELETE /{databases}/{setTable}/indexes/{index} endpoint
     * properly deletes a index.
     */
    @Test
    public void deleteIndexTest() {
        Index testIndex = Fixtures.createTestIndexOneField();
        f.insertIndex(testIndex);
        //act
        given().expect().statusCode(204).when().delete(testIndex.getName());
        //check
        expect().statusCode(404).when().get(testIndex.getName());
    }

}