es.iti.wakamiti.rest.RestSupport Maven / Gradle / Ivy
The newest version!
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package es.iti.wakamiti.rest;
import es.iti.wakamiti.api.WakamitiAPI;
import es.iti.wakamiti.api.WakamitiException;
import es.iti.wakamiti.api.util.http.oauth.Oauth2Provider;
import es.iti.wakamiti.api.datatypes.Assertion;
import es.iti.wakamiti.api.plan.DataTable;
import es.iti.wakamiti.api.plan.Document;
import es.iti.wakamiti.api.util.*;
import es.iti.wakamiti.api.util.http.oauth.Oauth2ProviderConfig;
import es.iti.wakamiti.rest.log.RestAssuredLogger;
import io.restassured.RestAssured;
import io.restassured.config.RestAssuredConfig;
import io.restassured.http.ContentType;
import io.restassured.http.Header;
import io.restassured.response.Response;
import io.restassured.response.ValidatableResponse;
import io.restassured.specification.RequestSpecification;
import org.apache.xmlbeans.XmlObject;
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
import org.slf4j.Logger;
import java.io.File;
import java.net.URL;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static es.iti.wakamiti.api.util.http.oauth.Oauth2Provider.ACCESS_TOKEN;
import static org.apache.commons.lang3.StringUtils.isBlank;
/**
* @author Luis Iñesta Gelabert - [email protected] | [email protected]
*/
public class RestSupport {
public static final Logger LOGGER = WakamitiLogger.forName("es.iti.wakamiti.rest");
protected final Map contentTypeValidators = WakamitiAPI.instance()
.extensionManager()
.getExtensions(ContentTypeHelper.class)
.collect(Collectors.toMap(ContentTypeHelper::contentType, Function.identity()));
protected URL baseURL;
protected String path;
protected String subject;
protected Matcher httpCodeAssertion;
protected Response response;
protected ValidatableResponse validatableResponse;
protected Oauth2Provider oauth2Provider = new Oauth2Provider().setRetriever(this::retrieveOauthToken);
protected Optional> authSpecification = Optional.empty();
protected List> specifications = new LinkedList<>();
protected static void config(RestAssuredConfig config) {
RestAssured.config = config;
}
protected RequestSpecification newRequest() {
response = null;
validatableResponse = null;
RequestSpecification request = RestAssured.given()
.accept(ContentType.ANY)
.header("Accept-Language", "*");
specifications.forEach(specification -> specification.accept(request));
authSpecification.ifPresent(specification -> specification.accept(request));
return attachLogger(request);
}
private RequestSpecification attachLogger(RequestSpecification request) {
RestAssuredLogger logFilter = new RestAssuredLogger();
if (LOGGER.isDebugEnabled()) {
request.log().all().filter(logFilter);
request.expect().log().all();
} else {
request.log().ifValidationFails().filter(logFilter);
request.expect().log().ifValidationFails();
}
return request;
}
protected void checkURL(URL url) {
if (!isBlank(url.getQuery())) {
throw new WakamitiException("Query parameters are not allowed here. Please, use steps for that purpose.");
}
}
protected String uri() {
if (baseURL == null) throw new WakamitiException("Missing required base URL.");
String base = baseURL.toString();
if (base.endsWith("/")) {
base = base.substring(0, base.length() - 1);
}
StringBuilder url = new StringBuilder(base);
if (path != null) {
url.append("/").append(path);
}
if (subject != null) {
url.append("/").append(subject);
}
return url.toString();
}
protected ValidatableResponse commonResponseAssertions(Response response) {
return response.then()
.statusCode(httpCodeAssertion);
}
protected String retrieveOauthToken(Oauth2ProviderConfig oauth2ProviderConfig) {
RequestSpecification request = RestAssured.given().contentType(ContentType.URLENC)
.auth().preemptive()
.basic(oauth2ProviderConfig.clientId(), oauth2ProviderConfig.clientSecret())
.formParams(oauth2ProviderConfig.parameters());
return attachLogger(request)
.with().post(oauth2ProviderConfig.url())
.then().statusCode(200)
.body(ACCESS_TOKEN, Matchers.notNullValue())
.extract().body().jsonPath().getString(ACCESS_TOKEN);
}
protected void executeRequest(BiFunction function) {
this.response = function.apply(newRequest(), uri());
this.validatableResponse = commonResponseAssertions(response);
}
protected void executeRequest(
BiFunction function,
String body
) {
this.response = function.apply(newRequest().body(body), uri());
this.validatableResponse = commonResponseAssertions(response);
}
protected void assertFileExists(File file) {
if (!file.exists()) {
throw new WakamitiException("File '{}' not found", file.getAbsolutePath());
}
}
protected void assertResponseNotNull() {
if (response == null) {
throw new WakamitiException("The request has not been executed");
}
}
protected Map tableToMap(DataTable dataTable) {
if (dataTable.columns() != 2) {
throw new WakamitiException("Table must have 2 columns [name, value]");
}
Map map = new LinkedHashMap<>();
for (int i = 1; i < dataTable.rows(); i++) {
map.put(dataTable.value(i, 0), dataTable.value(i, 1));
}
return map;
}
protected Object parsedResponse() {
Object body = doTry(
() -> XmlUtils.xml(response.body().asString()),
() -> JsonUtils.json(response.body().asString()),
() -> response.body().asString()
);
Map result = new LinkedHashMap<>();
result.put("headers", response.headers().asList().stream()
.collect(Collectors.toMap(Header::getName, Header::getValue, this::collectIfDuplicated)));
result.put("body", body);
result.put("statusCode", response.statusCode());
result.put("statusLine", response.statusLine());
return body instanceof XmlObject
|| ContentType.fromContentType(response.contentType()) == ContentType.XML
? XmlUtils.xml("response", result)
: JsonUtils.json(result);
}
@SuppressWarnings("unchecked")
private Object collectIfDuplicated(Object oldObj, Object newObj) {
if (oldObj instanceof List) {
((List