blob: 3d4b1240fffe6c5848aff54dbb599da979b006fc [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.vxquery.rest;
import java.net.URI;
import java.util.concurrent.TimeUnit;
import javax.ws.rs.HttpMethod;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.vxquery.app.VXQueryApplication;
import org.apache.vxquery.app.util.LocalClusterUtil;
import org.apache.vxquery.app.util.RestUtils;
import org.apache.vxquery.rest.request.QueryRequest;
import org.apache.vxquery.rest.request.QueryResultRequest;
import org.apache.vxquery.rest.response.AsyncQueryResponse;
import org.apache.vxquery.rest.response.QueryResponse;
import org.apache.vxquery.rest.response.QueryResultResponse;
import org.apache.vxquery.rest.response.SyncQueryResponse;
import org.apache.vxquery.rest.service.VXQueryConfig;
import org.apache.vxquery.rest.service.VXQueryService;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import io.netty.handler.codec.http.HttpResponseStatus;
/**
* Abstract test class to be used for {@link VXQueryApplication} related tests.
* These tests are expected to use the REST API for querying and fetching
* results
*
* @author Erandi Ganepola
*/
public class AbstractRestServerTest {
protected static LocalClusterUtil vxqueryLocalCluster = new LocalClusterUtil();
protected static String restIpAddress;
protected static int restPort;
protected static VXQueryService vxQueryService;
@BeforeClass
public static void setUp() throws Exception {
vxqueryLocalCluster.init(new VXQueryConfig());
vxQueryService = vxqueryLocalCluster.getVxQueryService();
restIpAddress = vxqueryLocalCluster.getIpAddress();
restPort = vxqueryLocalCluster.getRestPort();
}
@AfterClass
public static void tearDown() throws Exception {
vxqueryLocalCluster.deinit();
}
protected static String normalize(String string) {
if (string == null) {
return null;
}
return string.replace("\r\n", "").replace("\n", "").replace("\r", "");
}
protected static void checkMetrics(QueryResponse response, boolean showMetrics) {
if (showMetrics) {
Assert.assertTrue(response.getMetrics().getCompileTime() > 0);
Assert.assertTrue(response.getMetrics().getElapsedTime() > 0);
} else {
Assert.assertTrue(response.getMetrics().getCompileTime() == 0);
Assert.assertTrue(response.getMetrics().getElapsedTime() == 0);
}
}
protected static void checkResults(AsyncQueryResponse response, boolean compileOnly) {
if (compileOnly) {
Assert.assertNull(response.getResultUrl());
Assert.assertEquals(0, response.getResultId());
} else {
Assert.assertTrue(response.getResultUrl().startsWith(Constants.RESULT_URL_PREFIX));
Assert.assertNotEquals(0, response.getResultId());
}
}
protected static void checkResults(SyncQueryResponse response, boolean compileOnly) {
if (compileOnly) {
Assert.assertNull(response.getResults());
} else {
Assert.assertNotNull(response.getResults());
Assert.assertFalse(response.getResults().isEmpty());
}
}
/**
* Submit a {@link QueryRequest} and fetth the resulting
* {@link AsyncQueryResponse}
*
* @param uri
* uri of the GET request
* @param accepts
* application/json | application/xml
* @param method
* Http Method to be used to send the request
* @return Response received for the query request
* @throws Exception
*/
protected static <T> T getQuerySuccessResponse(URI uri, String accepts, Class<T> type, String method)
throws Exception {
CloseableHttpClient httpClient = HttpClients.custom().setConnectionTimeToLive(20, TimeUnit.SECONDS).build();
try {
HttpUriRequest request = getRequest(uri, method);
if (accepts != null) {
request.setHeader(HttpHeaders.ACCEPT, accepts);
}
try (CloseableHttpResponse httpResponse = httpClient.execute(request)) {
Assert.assertEquals(HttpResponseStatus.OK.code(), httpResponse.getStatusLine().getStatusCode());
if (accepts != null) {
Assert.assertEquals(accepts, httpResponse.getFirstHeader(HttpHeaders.CONTENT_TYPE).getValue());
}
HttpEntity entity = httpResponse.getEntity();
Assert.assertNotNull(entity);
String response = RestUtils.readEntity(entity);
return RestUtils.mapEntity(response, type, accepts);
}
} finally {
HttpClientUtils.closeQuietly(httpClient);
}
}
/**
* Fetch the {@link QueryResultResponse} from query result endpoint once the
* corresponding {@link QueryResultRequest} is given.
*
* @param resultRequest
* {@link QueryResultRequest}
* @param accepts
* expected
*
* <pre>
* Accepts
* </pre>
*
* header in responses
* @param method
* Http Method to be used to send the request
* @return query result response received
* @throws Exception
*/
protected static QueryResultResponse getQueryResultResponse(QueryResultRequest resultRequest, String accepts,
String method) throws Exception {
URI uri = RestUtils.buildQueryResultURI(resultRequest, restIpAddress, restPort);
CloseableHttpClient httpClient = HttpClients.custom().setConnectionTimeToLive(20, TimeUnit.SECONDS).build();
try {
HttpUriRequest request = getRequest(uri, method);
if (accepts != null) {
request.setHeader(HttpHeaders.ACCEPT, accepts);
}
try (CloseableHttpResponse httpResponse = httpClient.execute(request)) {
if (accepts != null) {
Assert.assertEquals(accepts, httpResponse.getFirstHeader(HttpHeaders.CONTENT_TYPE).getValue());
}
Assert.assertEquals(httpResponse.getStatusLine().getStatusCode(), HttpResponseStatus.OK.code());
HttpEntity entity = httpResponse.getEntity();
Assert.assertNotNull(entity);
String response = RestUtils.readEntity(entity);
return RestUtils.mapEntity(response, QueryResultResponse.class, accepts);
}
} finally {
HttpClientUtils.closeQuietly(httpClient);
}
}
/**
* Creates a POST or GET request accordingly from the given {@link URI}
*
* @param uri
* URI to which the request us to be sent
* @param method
* Http method- GET or POST
* @return request
*/
protected static HttpUriRequest getRequest(URI uri, String method) {
HttpUriRequest request;
switch (method) {
case HttpMethod.POST:
request = new HttpPost(uri);
break;
case HttpMethod.GET:
default:
request = new HttpGet(uri);
}
return request;
}
}