io.pivio.server.document.SearchApiTest.java Source code

Java tutorial

Introduction

Here is the source code for io.pivio.server.document.SearchApiTest.java

Source

package io.pivio.server.document;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.pivio.server.AppLauncher;
import io.pivio.server.JsonMapperConfiguration;
import io.pivio.server.TestHelper;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.io.IOException;
import java.net.URLEncoder;

import static org.assertj.core.api.Assertions.assertThat;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(AppLauncher.class)
@WebIntegrationTest(randomPort = true)
public class SearchApiTest {

    @Value("${local.server.port}")
    private int port;

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    private final TestRestTemplate restTemplate = new TestRestTemplate();

    private ObjectMapper objectMapper;
    private ObjectNode teamLambdaQuery;

    @Before
    public void initializeTestData() {
        TestHelper.cleanElasticsearch(elasticsearchTemplate);

        objectMapper = new JsonMapperConfiguration().objectMapper();

        addDocument(objectMapper.createObjectNode().put("id", "no1").put("name", "User Service")
                .put("short_name", "USS").put("type", "service").put("description", RandomStringUtils.random(20))
                .put("owner", "lambda").put("newfield1", "test1"));
        addDocument(objectMapper.createObjectNode().put("id", "no2").put("name", "Micro Service 2")
                .put("short_name", "MSS 2").put("type", "service").put("description", RandomStringUtils.random(20))
                .put("owner", "lambda"));
        addDocument(objectMapper.createObjectNode().put("id", "no3").put("name", "Micro Service 3")
                .put("short_name", "MSS").put("type", "service").put("description", RandomStringUtils.random(20))
                .put("owner", "lambda").put("newfield1", "test2").put("newfield2", "test"));
        addDocument(objectMapper.createObjectNode().put("id", "no4").put("name", "Service 4")
                .put("short_name", "MSS").put("type", "service").put("description", RandomStringUtils.random(20))
                .put("owner", "other").put("newfield1", "test3"));

        addDocument(objectMapper.createObjectNode().put("id", "nestedObject").put("name", "Service 5")
                .put("short_name", "NOS").put("type", "service").put("description", RandomStringUtils.random(20))
                .put("owner", "nestedTeam")
                .set("software_dependencies", objectMapper.createArrayNode()
                        .add(objectMapper.createObjectNode().put("name", "de.websitename:file.jar").set("licences",
                                objectMapper.createArrayNode()
                                        .add(objectMapper.createObjectNode().put("key", "prop").put("fullName",
                                                "Some Proprietary License"))))
                        .add(objectMapper.createObjectNode().set("licences",
                                objectMapper.createArrayNode()
                                        .add(objectMapper.createObjectNode().put("key", "apl").put("fullName",
                                                "Apache Public License"))
                                        .add(objectMapper.createObjectNode().put("key", "gpl").put("fullName",
                                                "GNU Public License"))))));

        addDocument(objectMapper.createObjectNode().put("id", "array").put("name", "Service Array")
                .put("short_name", "ARR").put("type", "service").put("description", RandomStringUtils.random(20))
                .put("owner", "arrayTeam")
                .set("arrayfield", objectMapper.createArrayNode().add("a").add("c").add("bb").add("bd")));

        addDocument(objectMapper.createObjectNode().put("id", "array2").put("name", "Service Array 2")
                .put("short_name", "ARR2").put("type", "service").put("description", RandomStringUtils.random(20))
                .put("owner", "arrayTeam")
                .set("arrayfield", objectMapper.createArrayNode().add("d").add("b").add("e")));

        elasticsearchTemplate.refresh(PivioDocument.class, true);

        teamLambdaQuery = objectMapper.createObjectNode();
        ObjectNode match = teamLambdaQuery.putObject("match");
        match.put("owner", "lambda");
    }

    @Test
    public void returnsAllDocumentsMatchingSearchCriteria() throws IOException {
        ObjectNode searchQuery = objectMapper.createObjectNode();
        ObjectNode match = searchQuery.putObject("match");
        match.put("name", "Micro");

        ArrayNode searchResult = executeSearch(searchQuery, "", "");

        assertThat(searchResult.findValues("id")).extracting(JsonNode::textValue).containsOnly("no2", "no3");
    }

    @Test
    public void onlyReturnsRequestedFieldsOfDocuments() throws IOException {
        ArrayNode searchResult = executeSearch(teamLambdaQuery, "newfield1,newfield2,", "");
        assertThat(searchResult.findValues("id")).extracting(JsonNode::textValue).containsOnly("no1", "no2", "no3");
        assertThat(searchResult.get(0).fieldNames()).containsOnly("id", "newfield1", "newfield2");
    }

    @Test
    public void sortResultsDescendingByshort_nameField() throws IOException {
        ArrayNode searchResult = executeSearch(teamLambdaQuery, "newfield1", "short_name:desc");
        assertThat(searchResult.findValues("id")).extracting(JsonNode::textValue).containsExactly("no1", "no3",
                "no2");
    }

    @Test
    public void sortResultsAscendingByshort_nameFieldWithCommaAfterFieldInParameter() throws IOException {
        ArrayNode searchResult = executeSearch(teamLambdaQuery, "newfield1", "short_name:asc,");
        assertThat(searchResult.findValues("id")).extracting(JsonNode::textValue).containsExactly("no2", "no3",
                "no1");
    }

    @Test
    public void sortResultsAscendingByshort_nameAndDescendingByTeamField() throws IOException {
        ObjectNode searchQuery = objectMapper.createObjectNode();
        searchQuery.putObject("match_all");

        ArrayNode searchResult = executeSearch(searchQuery, "", "short_name:asc,owner:desc");
        assertThat(searchResult.findValues("id")).extracting(JsonNode::textValue).containsExactly("no2", "array",
                "array2", "no4", "no3", "nestedObject", "no1");
    }

    @Test
    public void sortWithNotExistingFieldShouldGiveEmptyResultSet() throws IOException {
        ObjectNode searchQuery = objectMapper.createObjectNode();
        searchQuery.putObject("match_all");

        ResponseEntity<JsonNode> responseEntity = restTemplate
                .getForEntity(
                        "http://localhost:" + port + "/document?query="
                                + URLEncoder.encode(searchQuery.toString(), "UTF-8") + "&sort=notexisting:asc",
                        JsonNode.class);
        assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
    }

    @Test
    public void queryForNestedObject() throws IOException {
        ObjectNode searchQuery = objectMapper.createObjectNode();
        ObjectNode nested = searchQuery.putObject("nested");
        nested.put("path", "software_dependencies.licences");
        ObjectNode nestedQuery = nested.putObject("query");
        ObjectNode matchQuery = nestedQuery.putObject("match");
        matchQuery.put("key", "gpl");

        ArrayNode searchResult = executeSearch(searchQuery, "", "");
        assertThat(searchResult.findValues("id")).extracting(JsonNode::textValue).containsExactly("nestedObject");
    }

    @Test
    public void queryForValuesInArray() throws IOException {
        ObjectNode searchQuery = objectMapper.createObjectNode();
        ObjectNode matchQuery = searchQuery.putObject("match");
        matchQuery.put("arrayfield", "bd");

        ArrayNode searchResult = executeSearch(searchQuery, "", "");
        assertThat(searchResult.findValues("id")).extracting(JsonNode::textValue).containsExactly("array");
    }

    @Test
    public void queryForValuesInManyArrays() throws IOException {
        ObjectNode searchQuery = objectMapper.createObjectNode();
        ObjectNode matchQuery = searchQuery.putObject("prefix");
        matchQuery.put("arrayfield", "b");

        ArrayNode searchResult = executeSearch(searchQuery, "", "");
        assertThat(searchResult.findValues("id")).extracting(JsonNode::textValue).containsExactly("array",
                "array2");
    }

    @Test
    public void queryForValuesWithColon() throws IOException {
        ObjectNode searchQuery = objectMapper.createObjectNode();
        ObjectNode matchQuery = searchQuery.putObject("match");
        matchQuery.put("software_dependencies.name", "websitename");

        ArrayNode searchResult = executeSearch(searchQuery, "", "");
        assertThat(searchResult.findValues("id")).extracting(JsonNode::textValue).containsExactly("nestedObject");
    }

    @Test
    public void badRequestOnEmptyFieldsParameter() throws IOException {
        ResponseEntity<JsonNode> responseEntity = restTemplate
                .getForEntity(
                        "http://localhost:" + port + "/document?query="
                                + URLEncoder.encode(teamLambdaQuery.toString(), "UTF-8") + "&fields=",
                        JsonNode.class);
        assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
    }

    @Test
    public void badRequestOnEmptySortParameter() throws IOException {
        ResponseEntity<JsonNode> responseEntity = restTemplate
                .getForEntity(
                        "http://localhost:" + port + "/document?query="
                                + URLEncoder.encode(teamLambdaQuery.toString(), "UTF-8") + "&sort=",
                        JsonNode.class);
        assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
    }

    @Test
    public void badRequestOnSortParameterWithMissingColon() throws IOException {
        ResponseEntity<JsonNode> responseEntity = restTemplate.getForEntity(
                "http://localhost:" + port + "/document?query="
                        + URLEncoder.encode(teamLambdaQuery.toString(), "UTF-8") + "&sort=short_nameasc",
                JsonNode.class);
        assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
    }

    @Test
    public void badRequestOnSortParameterWithWrongSortOrder() throws IOException {
        ResponseEntity<JsonNode> responseEntity = restTemplate.getForEntity(
                "http://localhost:" + port + "/document?query="
                        + URLEncoder.encode(teamLambdaQuery.toString(), "UTF-8") + "&sort=short_name:asce",
                JsonNode.class);
        assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
    }

    private void addDocument(JsonNode document) {
        ResponseEntity<JsonNode> responseEntity = restTemplate
                .postForEntity("http://localhost:" + port + "/document", document, JsonNode.class);
        assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.CREATED);
    }

    private ArrayNode executeSearch(JsonNode searchQuery, String fieldParameter, String sortParameter)
            throws IOException {
        String searchParameter = URLEncoder.encode(searchQuery.toString(), "UTF-8");
        if (StringUtils.isNotEmpty(fieldParameter)) {
            searchParameter += "&fields=" + fieldParameter;
        }
        if (StringUtils.isNotEmpty(sortParameter)) {
            searchParameter += "&sort=" + sortParameter;
        }

        try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
            HttpGet request = new HttpGet("http://localhost:" + port + "/document?query=" + searchParameter);
            request.setHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE);
            HttpResponse response = httpClient.execute(request);
            return (ArrayNode) objectMapper.readTree(EntityUtils.toString(response.getEntity(), "UTF-8"));
        }
    }
}